关于js作用域闭包的理解

闭包:就是当函数可以记住并访问所在的词法的作用域时,就产生了闭包,即使函数是在当前词法作用域之外执行。

一个循环闭包的经典例子:编写一段代码实现每秒一次依次输出1~5

最容易犯的错误:

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

运行结果:每秒一次都输出了6

这就是对于闭包的概念理解不清晰,这里的设计缺陷在于我们每次都假设i有一个临时副本,但是事实上它们共享一个变量i

于是我们希望在每次循环迭代的时候都有一个闭包作用域,我们马上想到的是用一个立即执行函数(IIFE)创建作用域

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

但是依旧没有预期效果,原因在于作用域是空的情况下封闭是无效的,IIFE中需要有内容才能实现预期,最后代码改进如下:

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

效果达成,这就是作用域闭包的应用,当然在es6中有了let声明会使这段代码更加简洁,只需要在我们的第一个demo中将var改为let就OK。

实际编程中常用到的例子还有:假设页面有五个div,想实现的效果是:点击第一个div时弹出1,点击第二个div时弹出2,以此类推。

实现方式也是利用闭包,和上面给出的例子大同小异,这里不做详述。

你可能感兴趣的:(JavaScript,JavaScript,作用域闭包)