在js引擎中对变量的存储主要有两种位置,堆内存和栈内存。栈内存提供js的运行环境(window全局作用域、函数执行的私有作用域),存储基本数据类型的值。堆内存存储引用数据类型的值,其中对象存储的是属性—值
对(键值对),函数存储的是字符串。
我们每次给变量存值或者执行函数的时候都会占用内存空间,如果一直这样下去,日积月累,电脑总会装不下的,所以我们需要释放内存空间。而JavaScript具有自动垃圾收集机制,执行环境会负责管理代码执行过程中使用的内存,这样我们无需关心内存使用问题,可以专注代码编写。
堆内存释放
常见的浏览器释放方式主要有两种:标记清除、计数清除。
标记方式
谷歌浏览器
当变量进入环境时就将其标记为进入环境
,当变量离开环境时将其标记为离开环境
。垃圾回收程序会每隔一段时间就会检测一下当前作用域中的内存(引用空间地址)是否被占用,如果没有被占用,在空闲的时候就会将其释放掉。
计数方式
ie和火狐等浏览器
计数方式会跟踪记录每个值被引用的次数,在当前作用域中,如果一个空间地址被占用一次,就会累加1,如果减少一次占用就会减1,直到引用次数变成0的时候,说明已经没有被占用了,在空闲的时候就将其释放掉了。
手动进行堆内存释放
将所有引用这个堆内存空间地址值的变量赋值为null,堆内存地址不再被占用,浏览器在空闲的时候就会把堆内存释放掉。
var obj={name:"li",age:45};
var obj2=obj;
obj=null;
obj2=null;
栈内存释放
全局栈内存
只有当页面关闭(应用程序退出)的时候才会被释放
函数执行
销毁
一般情况下都是函数执行完毕之后就被销毁了
function fn(x){
return x+3;
}
fn(1);
不销毁
函数当前作用域中如果有一个引用数据类型的值被外面的变量占用就不销毁
案例 1
var function fn(){
var num=2;
return function(){
console.log(num);
};
};
var f=fn();
案例 2
var ary=[];
function fn(){
ary=[1,2,3];
};
var f=fn();
案例 3
/*
全局作用域:
变量提升:
1 fn=aaafff111
2 var f = f1
fn(2)====私有作用域
形参赋值:
i=2
执行代码: f1
*/
function fn(i){
return function (n){//f1
console.log(n+(++i));
}
}
var f=fn(2);// 形成了不销毁的作用域,i=4
f(3);// f1(3)==n=3; 3+ 3=6
fn(5)(6);// i=6 n=6 6+6=12
f(4);// n=4; 4+4=8;
不立即销毁
等待函数执行完毕之后再销毁
function fn(x){
return function(y){
return x+y;
}
}
fn(1)(2);//fn(1)执行完毕不立即销毁,等待fn(1)(2)整体执行完毕后再销毁