什么是闭包,有哪些优缺点呢?
1.产生原因:
js语言中:全局变量和局部变量以及变量的作用域
2.一句话概括:
能够读取其他函数内部变量的函数
3.说具体点:
- 函数里面包含的子函数,子函数访问父函数的局部变量
- 通过return将子函数暴露在全局作用域,子函数就形成闭包
- 通过闭包,父函数的局部变量没有被销毁,可通过闭包去调用 ,但同时,这个局部变量也不会被全局变量污染
4.本质上:
闭包就是将函数内部和函数外部连接起来的一座桥梁
5.举一个例子:
function aa() { var a = 0; function b () { alert(a++); }; return b } var fun = aa(); fun(); //1
6.优点:
- 逻辑连续,当闭包作为另一个函数调用参数时,避免脱离当前逻辑而单独编写额外逻辑。
- 方便调用上下文的局部变量。
- 加强封装性,是第2点的延伸,可以达到对变量的保护作用。
7.使用闭包注意点(缺点):
- 由于闭包会使得函数中的变量都被保存在内存中,内存消耗很大,所以不能滥用闭包,否则会造成网页的性能问题,在IE中可能导致内存泄露。解决方法是,在退出函数之前,将不使用的局部变量全部删除。
- 闭包会在父函数外部,改变父函数内部变量的值。所以,如果你把父函数当作对象(object)使用,把闭包当作它的公用方法(Public Method),把内部变量当作它的私有属性(private value),这时一定要小心,不要随便改变父函数内部变量的值。
8.应用场景:
1.setTimeout
//原生的setTimeout传递的第一个函数不能带参数 setTimeout(function(param){ alert(param) },1000) //通过闭包可以实现传参效果 function func(param){ return function(){ alert(param) } } var f1 = func(1); setTimeout(f1,1000);
2.函数防抖
/* * fn [function] 需要防抖的函数 * delay [number] 毫秒,防抖期限值 */ function debounce(fn,delay){ let timer = null //借助闭包 return function() { if(timer){ clearTimeout(timer) //进入该分支语句,说明当前正在一个计时过程中,并且又触发了相同事件。所以要取消当前的计时,重新开始计时 timer = setTimeOut(fn,delay) }else{ timer = setTimeOut(fn,delay) // 进入该分支说明当前并没有在计时,那么就开始一个计时 } } }
9.思考题:
题1
var name = "The Window"; var object = { name : "My Object", getNameFunc : function(){ return function(){ return this.name; }; } ; alert(object.getNameFunc()());
题2
var name = "The Window"; var object = { name : "My Object", getNameFunc : function(){ var that = this; return function(){ return that.name; }; } }; alert(object.getNameFunc()());
参考阮一峰大哥讲解的内容:
http://www.ruanyifeng.com/blog/2009/08/learning_javascript_closures.html
分享一刻:
一个浏览器 JS 库,通过摄像头,实时捕捉用户的动作,生成 2D 动画。