Blog
Blog copied to clipboard
认识闭包
何为闭包
1)官方一点说,能够读取其他函数内部的局部变量的函数,即为闭包。 抓住几个点:
- 它自身是个函数
- 访问其他函数,即非自身函数内
- 局部变量
2)从表现上来认识: 一个函数A里定义了另一个函数B,B读取了A的局部变量
3)从特性上去认识:函数内定义的局部变量,会随着函数的执行完毕而被销毁,内存被回收。但是在闭包存在的情况下,局部变量被闭包函数引用,因此没有被立即销毁,还能被访问到,直到闭包不被引用,才回收内存。
function example() {
var a = 1;
return function () {
console.log(a);
}
}
var test = example();
test();
// 等于null取消对闭包的引用
test = null;
说白了,就是在js里,变量分为全局变量和局部变量两种,一般情况下全局变量在内存中常驻,局部变量常在于函数内,执行完毕就会被回收了。而闭包,能让局部变量常驻与内存,宛如全局变量,但作用域并没有全局变量那么“宽”,其他外部代码不能访问,仅闭包函数自身能访问。
我把它理解成“被隔离起来的全局变量”。
用途
- 用于定义私有变量和私有方法,如使用“模块模式”,不额外生产全局变量/方法,不污染全局环境。
- 在内存中维持一个变量,如可利用一套代码能创建出多套作用域环境下的同名变量。
function person(name) {
return function () {
console.log(name);
}
}
var dad = person('dad');
var mom = person('mom');
dad(); // dad
mom(); // mom
缺点
- 由于内存不被回收,容易造成大量内存使用,闭包使用不当会造成内存写漏
- 影响浏览器性能,处理速度等
使用注意
上面在特性上说了,局部变量直到闭包函数不被引用,才会被回收。这个很重要,如果你仅定义了闭包函数,却不让外界环境引用(如没有return
出去),则定义完毕之后就会被回收了,实际上并没有发挥到闭包的真正作用
// 这种情况下,`name`会被回收掉。
function example() {
var name = 'example';
function test() {
console.log(name);
}
}
// 这种情况下,`name`不会被回收掉。
function example() {
var name = 'example';
return function test() {
console.log(name);
}
}
var a = example();