javascript - 这个 JavaScript 闭包是如何工作的?

标签 javascript jquery closures

这是一些 JavaScript:

linkElem.click(function () {
    var data = linkElem.data();
    alert(''+data.mls + ' ' + data.id);
});

有效。

linkElem 是我在函数内的循环中创建的局部变量。我使用 jQuery 的 .data() 为其分配了一些数据。如果我没有调用 .click()linkElem 将在循环期间重新分配,然后在函数返回后回收。但是,我创建了一个引用 linkElem 的匿名函数。所以我不再确定发生了什么。

我的猜测是,在循环期间创建的所有匿名函数和 linkElem 都被赋予某种 UID,并移至持久/全局范围。它是否正确?无偿的细节将不胜感激。

最佳答案

是的,您的描述非常接近。 Javascript 函数调用的本地存储只是为局部变量分配的一 block 内存。如果您通过在被调用函数内部创建另一个函数来“捕捉”到这一点,那么存储将被保留,局部变量将继续存在,而不会意识到提供的函数他们的诞生可能早已死去。

重要的是要记住,只有 函数创建这样的存储区——像大括号包围的循环体这样的东西不是单独的存储区。因此,一个常见的错误是在一个函数中声明一个变量,然后在一个循环中创建的多个函数中重复使用它。这本质上并没有错,但效果可能会令人惊讶:

function whatever() {
  for (var i = 0; i < 3; ++i) {
    setTimeout(function() { alert(i); }, 5000);
  }
}

如果您运行它,您会看到三个警报,它们都显示“3”。为什么?因为它们都共享相同的“i”变量。您可以通过引入另一个功能层来避免这种情况:

function whatever() {
  for (var i = 0; i < 3; ++i) {
    setTimeout((function(private_i) { return function() { alert(private_i); }; })(i), 5000);
  }
}

“包装器”函数只是提供一个局部变量(参数“private_i”),循环变量“i”可以复制到其中。

关于javascript - 这个 JavaScript 闭包是如何工作的?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3015457/

相关文章:

javascript - 为什么这个 javascript 警报会触发两次?

javascript - 如何将预览文本添加到我的自定义自动完成中?

javascript - 复杂表合并 javascript & jquery 算法

ruby - 了解 Ruby 嵌套函数

javascript - 如何更改闭包中捕获的函数定义

javascript - 使用 css 模块如何定义多个样式名称

javascript - 使用 jQuery 锁定和解锁页面?

javascript - 调整和移动在 Canvas 上绘制的矩形

javascript - 无法获取当前行中第一个 TD 的值

ios - 在 Swift 2 中创建异步任务