虽然很少触及,但是网页也是有内存上限的,当 htmljavascript等数据大小超过上限时,浏览器可能会闪退或停止响应。本文将介绍网页的内存结构、Javascript 垃圾回收机制以及函数闭包。

网页内存结构:堆 + 栈 + 池

  • 池:存放常量
  • 栈:存放定义的变量和函数
  • 堆:存放对象(new)
1
2
3
4
5
// str存放在栈中,"hello world"存放在常量池中,str只是一个饮用
var str = "hello world";

// 在堆中开辟了一个对象,str2是对该对象的引用,而该对象是对"hello world"常量的引用,也就是二级引用
var str2 = new String("hello world");

案例分析

1
2
3
4
5
6
7
8
9
str1 = "hello";
str2 = String("hello");
str3 = new String("hello");
str1 == str2:true //比较的是前者和后者的值
str1 == str2:true
str2 == str3:true
str1 === str2:true //比较前者和后者的内存地址
str1 === str3:false
str2 === str3:false

image

Javascript垃圾回收机制

str3 为一个对象引用,当 str3 赋值为其他值的时候,原本的对象会被自动清除。

清除原理:垃圾回收器定期巡视堆中所有对象,当发现对象没人引用时,就清除。

也就是说,对象清除不是实时的,而是需要等待一定时间的。

函数闭包

函数在调用之前只存在栈中,只要一调用就会在堆中创建一个闭包空间,执行完成后就被回收。

闭包空间中在使用变量时,优先使用闭包空间中的变量,不管是在之前还是之后调用。如果在闭包空间中没有找到,则直接找全局变量,而不是父函数变量。

1
2
3
4
5
6
7
8
9
10
var num1 = 10;
var num2 = 20;
function func1(){
num1 = 5;
num2 = 10;
var num2; //此处定义了num2,所以上面对num2的修改是对这个变量的修改
}
fun1();
alert(num1); //5
alert(num2); //20
1
2
3
4
5
6
7
8
9
10
11
12
13
14
var num1 = 10;
var num2 = 20;
function func1(){
num1 = 5;
num2 = 10;
func2();
var num2;
}
function func2(){
num2 = 30; //此处修改了num2,闭包中没找到,直接找全局变量,而不是找fun1中的
}
fun1();
alert(num1); //5
alert(num2); //30

image