要了解闭包,需要先了解一下变量的作用域,目前也就是局部变量和全局变量,定义变量主要是使用let 和var,这个在前面博客有讲过他们的区别,就不细讲了。
什么是闭包
一个函数和对其周围状态(lexical environment,词法环境)的引用捆绑在一起(或者说函数被引用包围),这样的组合就是闭包(closure)。也就是说,闭包让你可以在一个内层函数中访问到其外层函数的作用域。在 JavaScript 中,每当创建一个函数,闭包就会在函数创建的同时被创建出来。
怎么形成闭包
- 函数嵌套
- 引用变量
闭包的简单示例
function f3(){
c=90;//声明了一个全局变量
}
f3()
alert(c)
function f4(){ //
var d=999;
function f5(){ //f5函数,就是闭包
alert(d); // 999
}
return f5;
}
var res = f4();
res()
注意:
- 函数外部不能直接访问函数内部的数据,但是通过闭包可以访问
- 函数执行完后,函数内部的局部变量 一般不存在,只有闭包中的变量才会存在
闭包的应用
- 创建具有特定功能的js文件
- 将所有的数据和功能封装在函数内部
- 只向外暴露一个方法 或者多个方法
- 模块的使用者 只需要通过模块暴露的对象去调用
看一个简单的实例:我们想在页面上添加一些可以调整字号的按钮。我们的文本尺寸调整按钮可以修改 body 元素的 font-size 属性。
function makeSizer(size) {
return function() {
document.body.style.fontSize = size + 'px';
};
}
var size12 = makeSizer(12);
var size14 = makeSizer(14);
var size16 = makeSizer(16);
size12,size14 和 size16 三个函数将分别把 body 文本调整为 12,14,16 像素。我们可以将它们分别添加到按钮的点击事件上。如下所示:
document.getElementById('size-12').onclick = size12;
document.getElementById('size-14').onclick = size14;
document.getElementById('size-16').onclick = size16;
闭包的缺点
- 函数执行完后,函数内部的变量没有释放,占用内存事件较长
- 容易造成内存泄漏
目前来说,能不使用闭包尽量不使用闭包,如果必须使用闭包要及时释放。