为什么需要IIFE创建新的范围? [英] why is IIFE needed to create a new scope?

查看:82
本文介绍了为什么需要IIFE创建新的范围?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

来自您不懂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一样工作吗?在我看来,他们两个都有一个带有新变量jfunction声明,这不会为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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆