闭包是什么?
闭包就是能够读取其他函数内部变量的函数。例如在javascript中,只有函数内部的子函数才能读取[局部变量],所以
闭包可以理解成“定义在一个[函数]内部的函数”。 在本质上,闭包是将函数内部和函数外部连接起来的桥梁
通俗一点说就是可以在函数外部访问到函数内部的变量,因为正常情况下函数外部是访问不到函数内部作用域变量的。
作用域分为什么?
作用域分为了,全局变量,函数变量和块级作用域
闭包的优点
可以重复使用变量并且不会造成变量污染,可以隔离作用域,不会全局污染
闭包结合了全局变量和局部变量的优点,可以用来定义私有属性和私有方法
全局变量可以重复使用,但是容易造成变量污染,局部变量仅在局部作用域内有效,不可以重复使用,不会造成变量
污染
闭包的缺点
比普通函数更占内存,会导致网页性能变差,在IE下容易造成内存泄漏,由于闭包长期驻留内存,则会导致内存泄漏
什么是内存泄漏
因为闭包就是能够访问外部函数变量的一个函数,而函数是必须保存在内存中的对象,所以位于函数执行上下文中的所
有变量也需要保存在内存中,这样就不会被回收,如果一旦循环引用或创建闭包,就会占据大量内存,可能会引起内存泄漏
如何避免内存泄露?
在退出函数之前,将不使用的局部变量全部删除 我们可以将暴露在外部的闭包变量置为null
//这段代码会导致内存泄露
window.onload = function(){
var el = document.getElementById("id")
el.onclick = function(){
alert(el.id)
}
}
//解决方法为
window.onload = function(){
var el = document.getElementById("id")
var id = el.id
el.onclick = function(){
alert(id)
}
el = null
}
怎么判断是不是闭包?
函数嵌套函数,内部函数被return,内部函数调用外部函数的局部变量
function a(){
var i=0;
function b(){
alert(++i);
}
return b;
}var c=a();
c();
简而言之,闭包的作用就是在a执行完并返回后,闭包使得Javascript的垃圾回收机制不会收回a所占用的资源,因为a
的内部函数b的执行需要依赖a中的变量
闭包的适用场景
封装功能时(需要使用私有的属性和方法),函数防抖、函数节流、函数柯里化、给元素伪数组添加事件需要使用元素的
索引值,使用防抖节流函数就是闭包的原理,导航栏获取下标使用
function throttle(fn, interval) {
let timer = null;
let firstTime = true;
return function() {
let args = Array.prototype.slice.call(arguments, 0);
let _this = this;
if(firstTime) {
fn.apply(_this, args);
firstTime = null;
}
if(timer) return;
timer = setTimeout(function() {
fn.apply(_this, args);
timer = null;
}, interval || 300)
}
}
限制一个函数在一定时间内只能执行一次。
小结
由于闭包会使得函数中的[变量]都被保存在内存中,[内存]消耗很大,所以不能滥用闭包,否则会造成网页的性能问题,
在IE中可能导致内存泄露。解决方法是,在退出函数之前,将不使用的局部变量全部删除。