MDN对闭包的定义为:
一个函数和对其周围状态(lexical environment,词法环境)的引用捆绑在一起(或者说函数被引用包围),这样的组合就是闭包(closure)。也就是说, 闭包让你可以在一个内层函数中访问到其外层函数的作用域。在 JavaScript 中,每当创建一个函数,闭包就会在函数创建的同时被创建出来。
也就是说,当外层函数的上下文已经被销毁了,我们依然可以访问到外层函数作用域下的值。
作用
闭包可以延展局部变量的生命周期。
缺点
函数内部的局部变量没有被释放,使得占用内存时间变长,容易造成内存泄漏。
题目
var data = [];
for (var i = 0; i < 3; i++) {
data[i] = function () {
console.log(i);
};
}
data[0]();
data[1]();
data[2]();
答案都是3。原因是:
当执行到data[0]函数前,此时全局上下文的VO为:
globalContext = {
VO: {
data: [...],
i: 3
}
}
执行到data[0]函数时,data[0]上下文中没有i值,所以会从globalContext.VO中查找,i为3,所以打印的结果是3。
data[1]、data[2]同理。
如果用闭包:
var data = [];
for (var i = 0; i < 3; i++) {
data[i] = (function (i) {
return function(){
console.log(i);
}
})(i);
}
data[0]();
data[1]();
data[2]();
当执行data[0]时,data[0]的匿名函数执行上下文中存有i:0,所以在data[0]执行时,能够在作用域链中找到i为0。结果打印就是0。