闭包: 外部函数中包裹另一个函数,并将该函数返回出去(函数的返回值为一个定义的函数)
优点: 保证变量不被全局污染,外部可以访问函数内部的变量
缺点: 执行完毕后变量不会释放,容易造成内存泄露
// 不会被全局变量污染
function fun() {
a = 0; //全局变量
var b = '' //闭包内变量
var fn = function () {
console.log(a);
}
return fn;
}
var res = fun()
var b = '用来污染闭包内变量,没污染成'
var a = 222; //全局变量
res()
// 正常情况下,res()访问的变量为全局的,全局变量是可以被修改的
// 又因为闭包中没修改,所以闭包优点:闭包内变量不会被全局变量所污染
// 原理:作用域,函数赋值特点有关
// 函数赋值特点:将一个定义的函数赋值给另一个变量xx,xx()实际上执行的就是定义函数
// 函数赋值,浅拷贝,牵一发动全身
闭包缺点:
function add() {
var x = 0;
console.log(++x);//验证普通函数,变量释放,每次执行都是初始化
return function () {
console.log(++x);//验证闭包中函数变量不释放,每次执行都是重新赋值
}
}
// 函数执行,变量释放
add(); //1
add(); //1
add(); //1
var res = add();
// 函数执行后变量没有被释放,容易导致内存泄露
res();
res();
res();
res();
res();
res();
利用立即执行函数解决闭包问题:
function test() {
var arr = [];
for (var i = 0; i < 10; i++) {
(function (n) { //相当于执行了十个立即执行函数,并把 i 的值赋值给对应的十个 j
arr[n] = function () {
document.write(n + ' ');
}
}(i))
}
return arr;
}
var myArr = test();
// 当函数被调用时,调用的 j 是每一个立即执行函数单独的 j。
for (var j = 0; j < 10; j++) {
myArr[j]();
}