闭包
Posted 郭郭郭牧鑫
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了闭包相关的知识,希望对你有一定的参考价值。
1、概念
闭包函数:声明在一个函数中的函数,叫做闭包函数。
闭包:内部函数总是可以访问其所在的外部函数中声明的参数和变量,即使在其外部函数被返回(寿命终结)了之后。
闭包的特点
1、让外部访问函数内部变量成为可能
2、局部变量会常驻在内存中
3、可以避免使用全局变量,防止全局变量污染
4、会造成内存泄漏(有一块内存空间被长期占用,而不被释放)
闭包就是可以创建一个独立的环境,每个闭包里面的环境都是独立的,并且互不干扰。闭包会发生内存泄漏,每次外部函数执行的时候,外部函数的引用地址不同,都会重新创建一个新的地址。但凡是当前活动对象中有被内部子集引用的数据,那么这个时候,这个数据不删除,保留一根指针给内部活动对象。大概意思就是说当外部函数运行结束甚至销毁时,局部的变量key=value,尽管key被垃圾回收机制给回收了,但是value仍不会被回收,会变成一个自由变量留下引用的指针。
/例子1/
function fn(){
var a = 0;
return function(){
alert(a);
}
}
var b = fn();
b(); //0
/例子2/
function fn(){
var lll= 0;
function fun(){
lll++;
console.log(lll);
}
return fun
}
var fun1 = fn();
fun1();//1
fun1();//2
fun1();//3
var fun2 = fn();
fun2();//1
fun2();//2
fun2();//3
这个例子,就是在返回函数中做了一个递增并打印的操作,把fn的返回函数给到fun1和fun2,当我向上面代码一样调用的时候呢,就会发现替他打印的不是12345,而是123123,那这是什么原因呢,这就回到了上边介绍的那句话:每次外部函数执行的时候,外部函数的引用地址不同,都会重新创建一个新的地址。所以说虽然fun1和fun2都是fn(),但是呢都创建了新地址,都是自己的,互不干扰。
/例子3/
var lll= 0;
function fn(){
function fun(){
lll++;
console.log(lll);
}
return fun
}
var fun1 = fn();
fun1();//1
fun1();//2
fun1();//3
var fun2 = fn();
fun2();//1
fun2();//2
fun2();//3
这个跟例子2是一样的道理,只是变量的位置发生了改变,但是呢,对于内部的fun来说,变量是外部函数的局部变量和全局变量来说都是一样的。
/例子4/
function fn(){
var a = 1;
return fun(){
return ++a;
}
}
console.log(fn()());//2
console.log(fn()());//2
console.log(fn()());//2
var nfn = fn();
console.log(nfn());//2
console.log(nfn());//3
console.log(nfn());//4
/例子5/
(function() {
var m = 0;
function getM() { return m; }
function seta(val) { m = val; }
window.g = getM;
window.f = seta;
})();
f(100);
console.info(g()); //100 闭包找到的是同一地址中父级函数中对应变量最终的值
(function(){ /* code */ })()是立即执行函数
/例子6/
var list = document.getElementsByTagName("li");
for(var i=0;i<list.length;i++){
(function(i){
list[i].onclick = function(){
console.log(i);
};
})(i);
}
以上是关于闭包的主要内容,如果未能解决你的问题,请参考以下文章