JavaScript闭包问题:为什么第二次调用outerFn会创建一个新的outerVar实例?
JavaScript Closure question: why is the second call to outerFn creating a new instance of outerVar?
我有一个JavaScript问题。让我引自《学习jQuery》一书,第389-390页。这个问题与闭包有关。
我不明白为什么第二次调用outerFn()不是重置outerVar的值,而是[是],而是创建一个新的outerVar实例,绑定到第二个函数调用的范围。
JavaScript是怎么做到的?关于JavaScript,我需要知道些什么才能自己推断出来?
电子邮件的其余部分是书中的引文。
function outerFn() {
var outerVar = 0;
function innerFn() {
outerVar++;
$('#example-7').print('outerVar = ' + outerVar);
}
return innerFn;
}
var fnRef = outerFn();
fnRef();
fnRef();
var fnRef2 = outerFn();
fnRef2();
fnRef2();
现在我们的函数调用有了更有趣的行为:outerVar = 1outerVar = 2outerVar = 1outerVar = 2我们得到了前两种效果的混合。对innerFn()的调用独立引用自增outerVar。注意,第二次调用outerFn()不是重置outerVar的值,而是创建一个新的outerVar的实例,绑定到第二个函数调用的作用域。的这样做的结果是,在上述调用之后,对fnRef()的另一个调用将输出值3,随后调用fnRef2()也会输出3。的两个计数器是完全分开的。
这就是闭包的全部思想。正如上述wiki链接的第一段所述:
在计算机科学中,闭包(也称为词法闭包、函数闭包或函数值)是一个函数以及该函数的非局部名称(自由变量)的引用环境。这样的函数被称为"封闭"其自由变量。引用环境在创建闭包时将非局部名称绑定到作用域中相应的变量,另外将它们的生命周期延长到至少与闭包本身的生命周期一样长。
这种行为并不是javascript特有的——在所有提供闭包支持的语言中都会发生这种情况
你可能想多了。
与往常一样,每次调用outerFn
时,它都会为该函数的特定调用创建一个新的outerVar
变量——这是它的局部作用域的一部分。因此,返回(或以某种方式传递)的特定outerFn
调用范围内的任何函数将继续访问该范围-闭包。
如果没有闭包,函数将被限制使用作为参数传递的变量。
为了能够使用在函数外部声明的变量,必须在创建函数时捕获这些变量。每次创建函数时,它都会捕获当前范围内的完整变量集。
outerVar只是函数outerFn中的一个局部变量。每次调用outerFn都会创建一组特定于该特定函数调用的新的局部变量。
如果你想让outerVar从一次调用到另一次调用都保留它的值,那么你需要在函数调用之间存在的outerFn之外的作用域中定义它(它可以是全局作用域,也可以是存在于函数级别之上的其他作用域)。
- 同一项怎么可能在一个实例中未定义,却在另一个实例上定义
- jQuery"焦点”;在一个实例中有效,但在其他实例中无效
- 当与另一个实例进行比较时,我的类实例如何隐式返回数字
- 为什么可以't我使用成员方法初始化一个实例
- 如何使用 JavaScript 正则表达式搜索除一个实例之外的所有内容
- 挖空视图模型函数仅影响最后一个实例
- 插件总是只得到最后一个实例,如何让它适用于多个元素
- arguments变量是的一个实例
- 使用javascript删除特定HTML实体(breadcrumb)的最后一个实例
- jquery获取类的下一个实例的值
- 如何使外部按钮只影响类的一个实例
- javascript中的Ruby插值在两个实例中的一个实例中不起作用
- 剑道网格:在Angular指令中获取一个实例
- 多个 xmlhttp 请求会导致除最后一个实例之外的所有实例的 readystate 都达不到 4
- Wordpress jQuery 脚本不会在具有 jQuery.noConflict 用法的一个实例上启动
- 如何将 url (http://example.com) 的一个实例限制为仅在客户端打开一次
- 在单个页面上使用此.js 2 次时,它仅适用于一个实例
- 查找给定工作日的下一个实例(即.星期一)与时刻.js
- 谷歌地图将边界限制在世界的一个实例中
- CKEditor 一个实例用于多个 ID