- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我一直在努力理解下面的代码:
var add = (function () {
var counter = 0;
return function () {return counter += 1;}
})();
add();
add();
add();
此处add
被赋予了匿名自调用函数的返回值——即函数function() { return counter += 1 }
。现在,第一次调用 add()
时,它会按预期返回 1
。但第二次 add()
被调用时返回 2
。
我的问题是,因为 counter
是在函数内部定义的,所以每次函数完成执行时 counter
不会消失吗?也就是说,在第一次调用 add()
后,将显示 1。现在我们离开了那个函数,所以 counter
不应该像 automatic
变量那样忘记它的先前值并从堆栈中销毁吗?
最佳答案
What is the lifetime of variables inside a self calling function in javascript
与任何其他类型的 JavaScript 函数中的变量相同:只要它们可以被引用,它们就会存在,这有时意味着包含它们的函数返回的时间已经过去很久了。
您的 counter
变量在 IIFE 返回后继续存在,因为它创建并返回的函数 (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);
}
在上面,helloBuilder
返回的函数关闭它的name
参数和它的counter
变量. (因为参数也存储在执行上下文的变量对象上。)所以我们可以看到调用两次后,有两个变量对象,每个对象都有自己的name
和counter
,我们要求 helloBuilder
创建的每个函数都引用了一个。
关于javascript - javascript中自调用函数内变量的生命周期是多少,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36832476/
我正在开发一个使用多个 turtle 的滚动游戏。玩家 turtle 根据按键命令在 Y 轴上移动。当危害和好处在 X 轴上移动时,然后循环并改变 Y 轴位置。我尝试定义一个名为 colliding(
我不明白为什么他们不接受这个作为解决方案,他们说这是一个错误的答案:- #include int main(void) { int val=0; printf("Input:- \n
我正在使用基于表单的身份验证。 我有一个注销链接,如下所示: 以及对应的注销方法: public String logout() { FacesContext.getCurren
在 IIS7 应用程序池中有一个设置 Idle-time out 默认是 20 分钟,其中说: Amount of time(in minutes) a worker process will rem
我是一名优秀的程序员,十分优秀!