垃圾回收
js具有自动垃圾回收机制,无需手动清除
标记清楚
原理:当js中声明一个变量的时候,将变量标为“进入环境”,则变量在内存中占有位置,当变量执行完毕,会将其标记为“离开环境”js垃圾回收机制检测到“离开环境”就会自动回收
在标准浏览器下常用这个回收方式,只是时间间隔不一样
引用计数
原理:js会跟踪每一个变量的引用次数,当变量被声明,并将一个值赋给变量,则引用计数会标注为1,如果变量执行元素或有进行了赋值,则引用计数进行加1,相反,变量赋给其他变量,或者没再进行操作,则次数减1,直到次数变为0,则回收销毁
如果出现循环引用,a调用b,b调用a,则内存会一直没有释放,容易出现内存泄漏
内存泄漏和溢出的区别
内存泄漏:动态给内存分配空间,在使用完毕之后,没有进行释放,直到程序结束
内存溢出:不顾堆栈分配的数据大小,向内存写入过多的数据,导致数据越界
栈和堆的销毁方式
栈内存
全局变量:只有浏览器关闭的时候才会回收
局部变量:只有定义在函数里的才是局部变量,函数会产生自己的作用域,当函数执行完毕时,js内存机制会自动进行释放
堆内存
对象或函数在堆内存开辟空间,堆内存就会生成一个引用地址,如果有代码引用了这个地址,则对象不会被销毁。
如果想销毁,需要把引用设置成null即可
例如:
varx=new Array()
x=null//销毁了
不被销毁特殊情况
- 函数执行时,返回了一个对象,并在函数外调用,则私有变量不会被销毁
function fun(){//延长作用域链
var x=[1,2,3]
return x
}
var arr=fun()
console.log(arr)//数组可以在函数内访问,不会被销毁
- 在一个私有作用域中,给dom元素绑定事件,这个私有作用域不被销毁
var btn=document.getElementById("btn")
btn.οnclick=function(){
var num=11
alert(num)
}
-
闭包(特殊作用域)
闭包是能够有权访问其他函数内部的私有变量的函数,可以理解为函数嵌套函数。
必须满足以下特点,缺一不可:
- 函数嵌套函数
- 内部函数访问外部函数的变量
- 变量不会被垃圾机制所回收
例如:
function fun(){
var a=22
console.log("fun")
return function (){
var b=1
return ++a+(++b)
}
}
var f=fun()
var v2=f()
console.log(v2)//输出14
var v3=f()
console.log(v3)//输出15
注意:fun只执行一次,a不被销毁,闭包执行多选,b每次执行都重新赋值成了1
闭包的作用:
- 可以模拟私有方法
- 用来实现对象的封装
- 用闭包可以访问缓存(存在本地的),当代码执行时间过长,可以先从缓存中读取