1.什么是闭包
广义的说,一个变量一个函数就形成了一个闭包,典型的说:一个父函数,返回一个子函数,子函数调用父元素的局部变量,所以父函数的内存不能够释放,所以可以拓展了作用域。
借用于阮一峰老师的话:闭包就是能够读取其他函数内部变量的函数 链接地址
芳姐的闭包理解「函数」和「函数内部能访问到的变量」(也叫环境)的总和,就是一个闭包。链接地址
2.经典的闭包解析
var fn = function (){
var local = "hello"
function say(){
return local
}
return say
}
解析
- 有时候看到在闭包中有立即执行函数,但是这个不是必须的,2个不同的概念不好弄混
为了省略一个变量的申明,我可以用一个立即执行函数
(function(){
var local ='hello';
function say(){
return local
}
return say
})()
- 为什么要
return
一个函数呢?
如果不返回return,我们怎么访问这个变量,闭包的作用就是隐藏变量的同时,又可以访问到这个变量,如果不return,我们可以用window来得到
(function(){
var local ='hello';
window.say = function (){
local= local + 'world'
return local;
}
})()
这样也是一个闭包,一个函数访问了其他函数的局部变量。
3. 闭包的经典运用
- 修改代码让fnArri 输出 i
var fnArr = [];
for (var i = 0; i < 10; i ++) {
fnArr[i] = function(){
return i;
};
}
console.log( fnArr[3]() );
主要是当我们在调用的时候,js加载完成,此时i存放在全局变量中,循环结束后的值是10,所以会一直输出10
方法一:立即执行函数和闭包
var fnArr = [];
for(var i =0;i<10;i++){
fnArr[i]=(function (){
var n =i
return function(){
return n;
};
})(i)
}
简化
var fnArr = [];
for(var i =0;i<10;i++){
fnArr[i]=(function (n){
return function(){
return n;
};
})(i)
}
var fnArr = [];
for(var i =0;i<10;i++){
fnArr[i]=(function (){
var n=i
return function(){
return n;
};
})() //这里不用传递参数
}
方法二: 闭包
var fnArr = [];
for(var i =0;i<10;i++){
(function (){
var n = i;
fnArr[i]=function (){
return n
}
})()
}