闭包
闭包 : 当内部函数被保存到外部时,将会生成闭包。
缺点: 闭包会导致原有的作用域链不释放,造成内部泄漏。(存的东西多了,内存就少了,像内存泄漏了一样。)
闭包作用:
1.实现公有变量
eg:函数累加器
function add(){
var count = 0;
function demo(){
count ++;
console.log(count);
}
return demo;
}
var counter = add();
counter(); //调用几次counter(),就从零累加几次,实现函数累加器的作用
2.可以做缓存(存储结构)
eg:eater
function test(){
var num = 100;
function a(){
num ++;
console.log(num);
}
function b(){
num --;
console.log(num);
}
return[a,b];
}
var myArr = test();
myArr[0](); //101
myArr[1](); //100
3.可以实现封装,属性私有化
eg:Person()
4.模块化开发,防止污染全局变量
形成闭包的形式:
function test(){
//定义一个空数组
var arr = [];
// for循环是为了填满这个空数组,数组里有十条数据,每一条都是一个function。
for(var i = 0;i < 10;i++){
// arr里的 i 是随循环一直在变得,但是函数里的 i 是不变的,它是把整个函数体直接赋值给arr里对应的 i。
// 这个时候函数没有被执行。
arr[i] = function(){
document.write(i + ' ');
}
} //当循环执行完时,i 已经变为了10,被返回。(因为只有i = 10时,循环才能不在往下执行,被返回。)
//将arr保存到外部,相当于把十个函数体一同保存到了外部
return arr;
}
// 设置一个变量取保存这十个函数体,形成一个新数组。
var myArr = test();
// 返回数组里每一个函数体的值 (这个时候函数才被执行)
// 每一个函数体访问的 i = 循环执行完时被保存出来的i (i = 10)
for (var j = 0;j < 10;j++){
myArr[j]();
}
利用立即执行函数解决闭包问题:
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]();
}