一、《高级程序设计》上,这样说:当在函数内部定义了其余函数时候,就建立了闭包。闭包有权访问包含函数内部的全部变量。也就是数组
函数嵌套函数,内部函数能够引用外部函数的参数和变量,参数和变量不会被垃圾回收机制所收回。 |
这个引用才是关键,由于这个引用的存在,外部函数成了这个引用运行的上下文,迫使垃圾回收机制GC不能回收这条链上所占用的资源。而若是没有这个引用,则跟通常函数同样,函数运行完资源就会被回收。我看了做用域链的概念,感受看懂了做用域链,再来理解闭包就简单地多。闭包实质是内存中开辟一块地址,用于保存上下文。在另外一个函数内部定义的函数会将包含函数(即外部函数)的活动对象添加到它的做用域链中。闭包函数调用的外部函数变量都是引用,所以当执行相似于a[i]=function(){return i;}这种不能当即执行的出结果给数组赋值时候,就会出现问题。解决办法就是使用匿名函数进行当即执行出结果。这样函数参数按值传递,至关于在这个内部函数中又建立并返回了一个闭包,每一个函数都有本身的参数,能够返回各自的值。浏览器
另外关于this,因为匿名函数执行环境具备全局性,this一般指向window。每一个函数在被调用时候,会自动取得两个变量:this arguments。闭包函数只会搜索到自身活动对象上,不可能直接访问外部函数中的这两个变量。所以闭包
var name="haha"函数
var object={this
name:"hehe";spa
getName:function(){return function(){this.name;}}//这里的this指向window设计
};code
object.getName()();//haha对象
二、闭包有什么好处呢内存
1)但愿一个变量长期驻扎在内存中
2)能够避免全局变量的污染
三、闭包须要注意的地方
闭包在ie阅览器下很容易引起内存泄漏。页面跳转的时候,变量不进行释放,一直存在内存中,使得cpu累加提升,只有关闭浏览器的时候才会释放。
window.onload = function(){ |
var oDiv = document.getElementById('div1'); |
//一个对象属性引用一个内部函数,而这个内部函数又去引用外部对象,就会出现内存泄漏问题 |
oDiv.onclick = function(){ |
alert(oDiv.id); |
}; |
//解决办法 |
window.onunload = function(){ |
oDiv.onclick = null; |
}; |
}; |
另外一种作法: |
window.onload = function(){ |
var oDiv = document.getElementById('div1'); |
var id = oDiv.id; //提早创建变量 |
oDiv.onclick = function(){ |
alert(id); |
}; |
oDiv = null; //是对象为空 |
}; |