1.垃圾回收
JavaScript 中的内存管理是自动执行的,而且是不可见的。我们创建基本类型、引用类型、函数,所有这些都需要内存。
当已经不需要某块内存时这块内存还存在着,为了防内存泄漏,引入了垃圾回收机制。间歇的不定期的寻找到不再使用的变量,并释放掉它们所指向的内存。
2.变量的周期
当一个变量的生命周期结束之后它所指向的内存就应该被释放。JavaScript有两种变量,全局变量和在函数中产生的局部变量。
- 局部变量的生命周期在函数执行过后就结束了,此时便可将它引用的内存释放(即垃圾回收),
- 全局变量生命周期会持续到浏览器关闭页面。
3.回收管理
JavaScript 中内存管理的主要概念是 可达性。
“可达性” 值就是那些以某种方式可访问或可用的值,它们被保证存储在内存中。
代码回收规则如下:
- 全局变量不会被回收。
- 局部变量会被回收,也就是函数一旦运行完以后,函数内部的东西都会被销毁。
- 只要被另外一个作用域所引用就不会被回收
JavaScript 引擎中有一个后台进程称为垃圾回收器,它监视所有对象,并删除那些不可访问的对象。
4.应用
闭包就是应用了JS的回收机制特性:
function a(){
var i=0;
function b(){
alert(++i);
}
return b;
}
var c=a();
c(); // 1
c(); // 2
c(); // 3
当函数a赋值给变量c,c引用了函数a内的函数b,致使b所在的作用域不会被销毁,b函数可以访问父级作用域内的变量,即使上级函数执行完后,作用域内的值也不会被销毁。
经典面试题:
for( var i = 0;i<5;i++) {
setTimeout(function() {
console.log(i);
},1000)
} //5,5,5,5,5
setTimout在for里面是异步执行的,在延迟输出的时候,i的值是全局变量,已经是5了,因此会输出 5,5,5,5,5
解决办法:
for (var i = 0; i < 5; i++) {
(function(n) {
setTimeout(function() {
console.log(n);
}, n * 1000)
})(i);
}
使用立即执行函数 把循环的值i传进定时器中,定时器获取的值n在立即执行函数的作用域当中,当定时器挂起时n不会被清空,最终输出为n的值