JavaScript 带闭包和 IIFE 的计数器
JavaScript counter with closure and IIFE
在 www.w3schools.com/js/js_function_closures.asp 上有一个闭包中计数器的基本示例,据我所知,这是一个 IIFE:
var add = (function () {
var counter = 0;
console.log(counter);
return function () {return counter += 1;}
})();
add();
add();
add();
// the counter is now 3
然而,在对范围、闭包和 IIFE 进行了数小时的阅读(不是第一次)并查看了其他简单示例之后,我仍然不明白为什么 var counter = 0;
行只执行一次。我在该行之后添加的控制台日志从不输出任何内容,就好像它从未被调用过一样。
为什么每次调用 add() 时计数器都不会重置为 0?我理解错了什么概念?谢谢你的帮助。
I still don't understand why the var counter = 0; line is only
executed once.
因为IIFE函数只调用了一次。 add()
调用执行此函数:
function () {return counter += 1;}
这是从 IIFE 返回的。您可以通过提供函数名称并检查正在执行的函数的名称来检查:
var add = (function iife() {
var counter = 0;
console.log(counter);
return function inner() {return counter += 1;}
})();
add.name; // `inner`, not `iife`
The console log I added right after that line never outputs anything,
as if it never gets called
不可能。它应该只输出一次 0
。
Javascript 引擎的第一步(在声明 add
之后)是初始化 add
,这会导致调用 IIFE,这会再次导致:
var add = function () {
return counter = counter++
}
因为IIFEreturns这个函数作为值要赋值给add
。分配给 add
的函数仍然可以访问 IIFE (var counter
) 的词法范围:即闭包。
每个 add()
都是对从 IIFE 返回的函数的调用,因此 var counter = 0
只被调用一次(在初始化 add
时)。
在 www.w3schools.com/js/js_function_closures.asp 上有一个闭包中计数器的基本示例,据我所知,这是一个 IIFE:
var add = (function () {
var counter = 0;
console.log(counter);
return function () {return counter += 1;}
})();
add();
add();
add();
// the counter is now 3
然而,在对范围、闭包和 IIFE 进行了数小时的阅读(不是第一次)并查看了其他简单示例之后,我仍然不明白为什么 var counter = 0;
行只执行一次。我在该行之后添加的控制台日志从不输出任何内容,就好像它从未被调用过一样。
为什么每次调用 add() 时计数器都不会重置为 0?我理解错了什么概念?谢谢你的帮助。
I still don't understand why the var counter = 0; line is only executed once.
因为IIFE函数只调用了一次。 add()
调用执行此函数:
function () {return counter += 1;}
这是从 IIFE 返回的。您可以通过提供函数名称并检查正在执行的函数的名称来检查:
var add = (function iife() {
var counter = 0;
console.log(counter);
return function inner() {return counter += 1;}
})();
add.name; // `inner`, not `iife`
The console log I added right after that line never outputs anything, as if it never gets called
不可能。它应该只输出一次 0
。
Javascript 引擎的第一步(在声明 add
之后)是初始化 add
,这会导致调用 IIFE,这会再次导致:
var add = function () {
return counter = counter++
}
因为IIFEreturns这个函数作为值要赋值给add
。分配给 add
的函数仍然可以访问 IIFE (var counter
) 的词法范围:即闭包。
每个 add()
都是对从 IIFE 返回的函数的调用,因此 var counter = 0
只被调用一次(在初始化 add
时)。