总结一句话:让一个局部变量能被外部环境引用到,从而这个局部变量不会被垃圾回收,就形成了闭包。
先上代码,一个最简单的闭包:
function f1(){
var n = 0;
function f2(){
n++;
return n;
}
return f2
}
var test = f1();
test() //1
test() //2
f1方法返回f2,f2方法中返回变量n,这样其实执行f1就是返回变量n了。可以把f1()当成一个变量。然后将这个变量负值给了test。正常来说局部变量n在执行完f1()后就会被垃圾回收,内存销魂掉。但是由于这一句:var test=f1(); 这个f1的局部变量n在外层被test引用了,所以垃圾回收机制不能销毁这个变量,一直保存在内存中。
所以现在第一步,执行test(),发生:局部变量n=0,加1,return出来1到外部。由于n被return到外部,也就是可以被外部环境引用到了,所以这个函数执行完后局部变量n不会被销毁,n=1还保存在内存中。
第二步,再执行test(),发生:局部变量n=1,加1,return出来2到外部,n=2会一直保存在内存中不会被销毁。
其实闭包之所以能存在,根本原因就是垃圾回收机制。这个机制也很简单不用长篇大论:在js中,函数执行完毕后,局部变量就会被销毁,内存中仅仅保存全局作用域。如果这个局部变量有被全局作用域引用,那这个局部变量则不会被销毁。这就是垃圾回收机制。
常用闭包的例子:
function closure() {
var pArray = document.getElementsByTagName("p");
for( var i=0; i<pArray.length; i++ ) {
(function(j){
pArray[j].onclick = function() {
alert(j);
}
})(i)
}
}
(function(){
function j() {}
j.prototype.hello = function(){
alert('hello')
}
return window.j = new j();
})()
网友评论