首页
内存模型
内存模型
版权声明:本文为原创内容,转载请声明出处。
原文地址:http://www.excelib.com/article/199/show

我们先来回顾一下上一节我们所学的内容:ES的本质是一个对象,一个对象可以包含多个属性,对象的属性可以分为直接量和对象两种类型,而对象又分为object对象和function对象两种类型。

内存模型

直接量和对象这两种类型在内存中保存的方式并不相同,直接量是直接用两块内存分别保存属性名和属性值,而对象需要三块内存,分别保存属性名、属性地址和属性内容。

直接量内存模型

直接量也叫“字面量”,在ES标准中的名称叫Literal,从翻译的角度来说应该“字面量”更加准确,不过翻译成汉语“直接量”可能更利于大家理解,所以学生在这里就叫“直接量”了。直接量指的就是ES中的简单类型,大家可以简单地理解为直接写值就可以的量,比如常用的数字、字符串等都是直接量。

在ES5.1中共规定了五种直接量:Null、Boolean、Numeric、String和RegularExpression(正则表达式),ES2015中又新增了一种模板直接量,学生会在ES2015中给大家详细介绍。

直接量在内存中是使用两块内存分别保存属性名和属性值的,结构如图1所示


图1

这种类型的主要特点是不同对象相互赋值后,他们之间不会相互影响,我们看下面的例子

1
2
3
4
5
6
7
window.a=1;
window.b=a;
console.log("a=",a,",b=",b);    //输出a= 1 ,b= 1
a=2;
console.log("a=",a,",b=",b);    //输出a= 2 ,b= 1
b=3;
console.log("a=",a,",b=",b);    //输出a= 2 ,b= 3


这里我们给window对象定义了一个直接量类型属性a,然后又定义了一个属性b,并将a赋值给他,接着分别修改了a和b的值,从上面的结果可以看出他们是互不影响的,这是因为他们在内存中都有自己的名值对内存空间,将a赋值给b的时候其实是将a的值复制了一份给了b。

对象类型内存模型

对象在内存中保存的方式跟直接量有本质的区别,对象是使用三块内存来保存的,他们分别保存对象名(对于其父对象来说就是属性名)、对象保存的地址和对象本身,结构如图2所示

图2

这种内存模型可以非常有效地节约内存,如果不同的对象包含一个相同的对象作为其属性的话,在内存中其实只有一份对象的内容,不同对象所包含的属性其实只是一个引用(内存地址)。

既然所使用的是同一个对象,那么他们之间对对象的修改就会相互影响了,我们来看下面的例子

1
2
3
4
5
6
7
8
9
10
function F(){     
    this.v = 1; 
var f = new F(); 
var f1 = f;
console.log(f1.v);            //输出1
f1.v=2;
console.log(f.v);              //输出2 
f = null
console.log(f1.v);             //输出2



这里首先定义了function类型的对象F,然后用其创建了object类型的对象f,这时变量f就会指向一个保存创建出来对象的地址,然后将f赋值给f1变量的操作又将f1指向了创建出来的对象,这时f和f1都指向了同一个对象,所以f1.v的值就是创建出来对象中默认的1,通过f1将v的值修改为2之后因为是修改的是同一个对象中属性v的值,所以使用f.v输出的也是2,最后将f设置为null的操作只是将其对应的地址设置为了null,但并不影响对象的内容,所以使用f1还可以调用,整个流程如图3所示

1.png

图3


ES中对象类型的模型类似于我们在Windows系统中所使用的快捷方式,同一个内容,比如一份Excel报表,可以在不同的文件夹下有很多快捷方式,不过无论通过哪个快捷方式打开报表修改内容后,所有快捷方式所打开的报表都会被修改,因为他们所对应的本来就是同一个报表。当然,删除了其中的一些快捷方式也并不会影响报表的内容。Windows中不同的文件夹就相当于ES中不同的对象,所包含的文件相当于ES中的直接量,快捷方式相当于对象属性。这种类比虽然不够严谨,不过用于理解ES的对象结构和内存模型还是比较直观的。