闭包

114 阅读1分钟

含义

一个函数和对其周围状态(lexical environment,词法环境)的引用捆绑在一起(或者说函数被引用包围),这样的组合就是闭包(closure)。也就是说,闭包让我们可以在一个内层函数中访问到其外层函数的作用域。在JS中,每创建一个函数,闭包就会在函数创建的同时被创建出来。
闭包 = 函数 + 声明该函数的词法环境。
词法(lexical)一词指的是,词法作用域根据源代码中声明变量的位置来确定改变量在何处可用。嵌套函数可访问声明于他们外部作用域的变量

function A () {
    const a = 123;
    window.B = function() {
        console.log(a)
    }
}
A();
B(); // 123

闭包不是函数嵌套函数,并返回一个函数。这个解释不够完整,比如上面的例子就可以反驳这个观点。

闭包解决 var定义函数问题

for(var i = 0; i < 6; i++) {
    setTimeout(function timer() {
        console.log(i)
    }, 0)
}
// 输出 6 个 6

setTimeout是一个异步函数,所以会等循环执行完成后再执行,此时i已经是6,所以最后输出都是6

闭包

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

我们利用立即执行函数,将i传入进去,所以在setTimeout回掉执行的时候,已经能访问到i对应的值

利用setTimeout的第三个参数

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

es6解决

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