为什么需要IIFE创建新的范围? [英] why is IIFE needed to create a new scope?
问题描述
来自您不懂JS :
for (var i=1; i<=5; i++) {
setTimeout( function timer(){
console.log( i );
}, i*1000 );
}
给予
6
6
6
6
6
但使用 IIFE
for (var i=1; i<=5; i++) {
(function(){
var j = i;
setTimeout( function timer(){
console.log( j );
}, j*1000 );
})();
}
给予
1
2
3
4
5
我的问题:为什么不
for (var i=1; i<=5; i++) {
setTimeout( function timer(){
var j = i;
console.log( j );
}, i*1000 );
}
或
for (var i=1; i<=5; i++) {
function timer() {
var j = i;
console.log(j);
}
setTimeout(timer, i*1000 );
}
像IIFE一样工作吗?在我看来,他们两个都有一个带有新变量j
的function
声明,这不会为i
的特定设置创建一个新的词法作用域吗?
work like the IIFE example? It seems to me they both have a function
declaration with a new variable j
, wouldn't that create a new lexical scope with a specific setting for i
?
推荐答案
IIFE的重要部分是它立即运行 ;在i
更改之前,它将读取其值并将其放入新变量中.在其他示例中,读取i
的函数– function timer()
–不会立即运行,并且在其新变量中添加的值是i
更改后的值.
The important part of the IIFE is that it runs right away; before i
changes, it reads its value and puts it in a new variable. The function reading i
in your other examples – function timer()
– does not run right away, and the value it puts in its new variable is the value of i
after it’s already changed.
此外,在ES6中,您可以使用let i = …
代替var i = …
,并且在没有IIFE或j
的情况下也可以正常工作:
Also, in ES6, you can just let i = …
instead of var i = …
and it’ll work fine without the IIFE or j
:
for (let i = 1; i <= 5; i++) {
setTimeout(function timer() {
console.log(i);
}, i * 1000);
}
因为let
具有块范围而不是函数范围,并且for
循环的初始化部分中声明的变量算在for
块的一半内.
because let
has block scope instead of function scope and variables declared in the initialization part of for
loops count as being half-inside the for
’s block.
这篇关于为什么需要IIFE创建新的范围?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!