我们前面已经认识了函式作用域,也了解了回调函式,但有时候会产生意想不到的事情,造成内存问题,其中一个是闭包
闭包通常出现在巢状函式中,是内部函式使用了外部函式的变数时,产生闭包!
首先我们用简单的范例
function fn() {
var a = 1;
function plus1() {
a++
console.log(a);
}
return plus1;
}
var f = fn();
f();
我们透过 Google Chrome 的开发人员工具查看执行过程
可以看到在执行到第 8 行的时候,产生了闭包,也就是红框处!
由此可见~闭包是在我们内部函式使用到了外部函式的变数时产生出来。
你可能想说第 9 行函式还没执行呀!?
那是因为,函式的提升,所以导致执行到函式变数的时候就产生闭包。
而这时有被内部函式使用的变数,就会存在闭包之中!
就是我们上面的范例
function fn() {
var a = 1;
function plus1() {
a++
console.log(a);
}
return plus1;
}
var f = fn();
f(); // 2
f(); // 3
你会发现!函式内的变数 a
还存在可以累加并没有消失,而这个值就存在 f
函式的闭包中!
没错!回调函式也会产生闭包~如下面范例
function consoleDelay (msg, time) {
setTimeout( function() {
console.log(msg)
}, time)
}
consoleDelay("我也是闭包", 2000);
一样有形成闭包的条件!内部函式引用了外部函式的变数!
一般函式执行完毕後,就会从内存释放,而闭包则是把函式内的变数,继续保留在内存中(延长了局部变数的生命周期)。
一般函式内的变数无法从外部操作,但闭包可以间接操控函式内部的变数值。
函式执行完後,函式内的局部变数不会释放,如果这个局部变数还会使用,那就是优点,如果不会使用了,那就变成缺点,因为占用内存的时间会变长。
function fn() {
var arr = new Array(10000);
function arrLength() {
console.log( "内存有 " + arr.length + " 长度的阵列" );
}
return arrLength;
}
var f = fn();
f(); // 内存有 10000 长度的阵列
容易造成内存溢出与泄漏
尽量避免滥用闭包
及时释放
f = null; // 让内部函式变成「垃圾物件」,浏览器会自动清除
我们已经逐步学习 JavaScript 的核心精随了!也是面试很长考的观念~
前情提要 我是 siriuskoan,在这三十天内会把一些关於 flask 的知识写成文章,以供自己...
如果,我留下足迹,却无人发现, 算不算可惜。 如果,我遇见了我的足迹, 却浑然不知, 何以证明,是...
Redis持久化 Redis持久化模式->AOF AOF (Append Only File)...
早起运动Day11 - 来自周遭的祝福 「你知道吗?当时最让我触动的地方,是你接受了我的情绪。...
今天一开始,我们先来讲讲基本的常识~~ 甚麽是位元、位元组? 位元(bit)可以保有两种资料(0 和...