版权说明:
本文部分内容引自《JavaScript高级程序设计(第3版)》第七章 函数表达式,如有侵权,请联系博主删除,博主邮箱 job_tom@foxmail.com
闭包是什么
闭包是指有权访问另一个函数作用域中的变量的函数。
闭包的作用
重用变量,同时又保护变量不被篡改;
闭包的优点
集合全局变量和局部变量的优点:既能在全局使用变量,又能避免全局污染;
闭包的实现方法
一,函数内嵌函数
创建闭包的常见方式,就是在一个函数内部创建另一个函数,如下示例:
function outer(){
var i=0;
return function(){ // 这个内部function,就是一个闭包
i+=1;
console.log(i);
}
}
var getNum=outer();
getNum();// 1
getNum();// 2
// 全局变量i位于第三作用域链,不会对输出结果造成影响
var i=0;
getNum();// 3
getNum();// 4
二,以对象的语法创建闭包
通过对象的语法依然可以创建闭包,如下示例:
var name = "The Window";
var object = {
name : "My Object",
getName: function(){
return this.name;
}
};
object.getName();// 'My Object'
闭包的缺点
过度使用闭包可能会占用大量内存,因为闭包会携带包含它的函数的作用域;
规避闭包缺点的方法
一,将引用过的变量置为null
// 一组伪代码:表示获取一个dom元素,并在点击该元素时显示此元素的id
// 这种做法,在闭包使用完成后把element置为null,等待垃圾收集器回收
// 这里要说一个问题,如果要释放的数据是一个数组(largeArr),
// 简单的将其置为null(largeArr = null),是有可能起不到回收作用的
// 因为如果有其他变量仍然在引用这个数组,那垃圾收集器就不会回收这块内存
// 在不确定是否有其他变量引用的情况下,数组的内存释放,建议使用largeArr = []来实现,
// 这样可以置空largeArr指针对应的堆中的数组为空数组
function assignHandler(){
var element = document.getElementById("someElement");
var id = element.id;
element.onclick = function(){
alert(id);
};
element = null;
}
assignHandler();
二,使用匿名函数自调,在功能完成时销毁
// 在1月1日那天发送一条消息,新年快乐
// 这种做法可以减少闭包占用的内存问题,因为没有指向匿名函数的引用,
// 所以只要函数执行完毕,就可以立即销毁其作用域链了
(function(){
var now = new Date();
if (now.getMonth() == 0 && now.getDate() == 1){
alert("Happy new year!");
}
})();
点击此超链接跳转到Tom哥的博文分类和索引页面
Tom哥的博客博文分类和索引页面地址:https://blog.csdn.net/tom_wong666/article/details/84137820