乐趣区

关于前端:JavaScript闭包从一道面试题说起

先看一段代码,并想出本人的答案:

    for(var i=0;i<5;i++){setTimeout(function(){console.log(i);
        },1000)
    }
    
    console.log(i);

不难得出,该题的答案是 5 5 5 5 5 5。
立刻输入一个 5,1 秒后输入 5 个 5。

如果这里想把答案变成:5 1 2 3 4 5。
那么,相熟闭包的同学,很快能够得出一个这样的办法:

    for(var i=0;i<5;i++){(function(j){   //j = i
            setTimeout(function(){console.log(j);
            },1000)
        })(i);
    }
    
    console.log(i);

如果对定时器很理解的话,咱们还能够用另一种形式:

    for(var i=0;i<5;i++){setTimeout(function(j){console.log(j);
        },1000,i)
    }
    
    console.log(i);

这里的 setTimeout 的第三个参数是可选项,示意提供给以后执行函数的其余参数

当然如果相熟 ES6 语法,很快就会想到将 var 改成 let,代码如下:

    for(let i=0;i<5;i++){setTimeout(function(){console.log(i);
        },1000)
    }
    
    console.log(i);

当然这种办法会报错,因为 i 值只在块级作用域内失效;
然而这种办法的确能够将定时器内打印进去的后果改为 1 2 3 4 5

闭包,艰深的来讲就是一个函数能够拜访另一个函数中的变量,防止变量被垃圾回收机制给回收。

最常见的闭包就是函数外部加一个子函数,通过子函数拜访函数的局部变量。

退出移动版