关于前端: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

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

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

评论

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

这个站点使用 Akismet 来减少垃圾评论。了解你的评论数据如何被处理