浅谈闭包(js closure)

2019-08-02  本文已影响0人  来碗鸡蛋面

原创声明

本文系作者辛苦码字所得,欢迎分享和转载,但请在明显位置注明作者的如下信息:
笔名:来碗鸡蛋面
简书主页:https://www.jianshu.com/u/4876275b5a73
邮箱:job_tom@foxmail.com
CSDN ID:tom_wong666

版权说明:

本文部分内容引自《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!");
}  
})();
上一篇 下一篇

猜你喜欢

热点阅读