1,闭包
1.1 概念
闭包就是在一个作用域里可以访问另一个局部作用域的局部变量时(一般特指子函数访问父函数内部的变量)这时就产生了一个闭包,被访问的变量所在的局部作用域就称为闭包函数
1.2 闭包的优缺点:
优点:延伸了变量的使用范围,因为闭包函数中的变量不会随着闭包函数销毁而销毁,而是要等到还在使用他的函数销毁时才会销毁
缺点:频繁使用闭包有造成内存泄漏的风险,由于闭包会将它的外部函数的作用域的变量也保存在内存中,因此会比其他函数更占用内存,这样的话,如果过度使用闭包,就会有内存泄露的威胁
1.3 解决闭包造成内存泄漏的问题
在使用完闭包函数的变量之后将该变量赋值null,触发js的回收机制
function f1() {
var a = '变量1' //f1里的这些被f2访问到的变量集合就称为闭包
var f2 = function () {
console.info(a)
}
a = null //在函数执行完之后销毁变量,触发js的回收机制,就不会有内存泄漏的风险了
return f2 // f1就是一个闭包函数,因为他的变量能被f2访问
}
var fn = f1() // 获得f1的变量 //"变量1"
2,内存泄漏
2.1 概念
内存泄漏(Memory Leak)是指程序中已动态分配的堆内存由于某种原因程序未释放或无法释放,造成系统内存的浪费,导致程序运行速度减慢甚至系统崩溃等严重后果
2.2 造成内存泄漏的方式
- 滥用全局变量可能会造成内存泄漏
- DOM的引用没有清除(绑定的事件之类)
- 闭包的使用(闭包会将外部函数的变量保存到内存中)
- 定时器没有清除
2.3 解决或者避免内存泄漏
- 减少全局变量的使用
- 使用闭包之后在函数执行完之后给变量赋值null,销毁变量
- 解绑DOM事件和清除定时器
3, js垃圾回收机制
1、JS的回收机制
js中变量分为局部变量和全局变量,局部变量的生命周期是函数执行完之后就销毁了,而全局变量的生命周期则是当浏览器窗口关闭的时候才销毁,所以滥用全局变量可能会导致内存泄漏
JavaScript垃圾回收的机制很简单:找出不再使用的变量,然后释放掉其占用的内存,但是这个过程不是实时的,因为其开销比较大,所以垃圾回收系统(GC)会按照固定的时间间隔,周期性的执行。
垃圾收集器必须跟踪到底哪个变量没用,对于不再有用的变量打上标记,以备将来收回其内存。用于标记的无用变量的策略可能因实现而有所区别,通常情况下有两种实现方式:标记清除和引用计数。引用计数不太常用,标记清除较为常用。
2、标记清除
js中最常用的垃圾回收方式就是标记清除。当变量进入环境时,例如,在函数中声明一个变量,就将这个变量标记为“进入环境”。从逻辑上讲,永远不能释放进入环境的变量所占用的内存,因为只要执行流进入相应的环境,就可能会用到它们。而当变量离开环境时,则将其标记为“离开环境”。