use*_*782 1 javascript variables lifetime
我一直在努力理解以下代码:
var add = (function () {
var counter = 0;
return function () {return counter += 1;}
})();
add();
add();
add();
Run Code Online (Sandbox Code Playgroud)
这里add
分配了匿名自调用函数的返回值 - 即函数function() { return counter += 1 }
.现在第一次add()
被调用它1
按预期返回.但第二次add()
称它返回2
.
我的问题是因为counter
在函数内定义所以不是每次函数完成执行counter
都应该死掉?也就是说,在第一次调用add()
1之后将显示.现在我们已经不在那个函数中,所以不应该counter
忘记它以前的值并且像automatic
变量一样从堆栈中销毁?
javascript中自调用函数内变量的生命周期是多少
与任何其他类型的JavaScript函数中的变量相同:只要它们可以被引用,它们就存在,这有时意味着包含它们的函数返回的时间已经很久了.
counter
在IIFE返回后,您的变量继续存在,因为它创建的函数和returns(return function () {return counter += 1;}
)是对变量的闭包.只要该函数存在,该变量就会存在.
更技术上:调用函数会为该调用创建一个称为执行上下文的东西,该调用具有变量环境对象.在调用期间创建的任何函数都会接收对该外部变量环境对象的引用; 与所有对象一样,该对象只要存在对它的引用就存在,因此这些函数使对象保持活动状态.变量实际上是该变量环境对象的属性,因此只要某些东西引用它们所在的对象,它们就会存在.(这是非常简化的形式.)虽然理论上保留了整个变量环境对象,但实际上,如果优化效果不可观察,JavaScript引擎可以自由优化,因此闭包实际上不使用的变量可能(或可能不)释放,具体取决于引擎和功能中的代码.
你的IIFE只能被调用一次,因此只能有一个counter
,但创建一个闭包的函数被多次调用是很常见的,在这种情况下,你有多个变量对象,以及关闭的变量的多个副本.
例:
function helloBuilder(name) {
var counter = 0;
return function() {
++counter;
display("Hi there, " + name + ", this is greeting #" + counter);
};
}
var helloFred = helloBuilder("Fred");
var helloMaria = helloBuilder("Maria");
helloFred(); // "Hi there, Fred, this is greeting #1"
helloFred(); // "Hi there, Fred, this is greeting #2"
helloMaria(); // "Hi there, Maria, this is greeting #1"
helloMaria(); // "Hi there, Maria, this is greeting #2"
helloFred(); // "Hi there, Fred, this is greeting #3"
function display(msg) {
var p = document.createElement('p');
p.appendChild(document.createTextNode(msg));
document.body.appendChild(p);
}
Run Code Online (Sandbox Code Playgroud)
在上面,返回的函数helloBuilder
关闭了它的name
参数和它的counter
变量.(因为参数也被存储在该执行上下文的变量对象.)因此,我们可以看到,调用了两次后,有两个变量对象,每个都有自己的name
和counter
,一个由我们要求每个函数引用的helloBuilder
创建.
归档时间: |
|
查看次数: |
607 次 |
最近记录: |