首页 > 代码库 > javascript内存模型分析猜想

javascript内存模型分析猜想

/*
* 这里我是利用分析java内存模型的方法来猜想javascript的内存模型,
* 由于没有看到国内有关于分析javascript的书籍,但是可以借鉴java的
* 内存模型结构来帮助理解javascript的内存模型中的原型机制,下面先
* 给出一个简单的原型例子

* */

"use strict";
function PrototypeModel(name,author,time){

}
PrototypeModel.prototype.name  = "PrototypeModel";
PrototypeModel.prototype.author = "felayman";
PrototypeModel.prototype.time = "2014-5-22";
PrototypeModel.prototype.getInfo = function(){
   return "关于对javascript的内存模型的测试";
};
/**
 * 例子很简单,只是为一个函数增加几个原型属性,下面开始利用java的
 * 内存模型来说明javascript,看是否可以解释出其原型思想
 * 
 * 在java中,引用类型变量和基本类型变量是存储在栈上,而对象则是存储
 * 在堆内存中,而关于加载到堆内存中的实例对象所属类的信息则是保存到
 * Class实例对象中,虽然Class实例也是对象,但是它并不保存在堆内存中
 * 而是存放到方法区中(详细内容参考深入立即JVM一书),而方法区中则保存
 * 类的一些静态属性和类的信息,那么我们是否可以理解,在javascript中
 * 函数能否理解为javascript中的类呢?虽然它们的名称不同,但是还是有
 * 很多相同的地方,因为它们都充当着对象实例的模板,即类.因为javascript
 * 是属于函数式编程的语言,是基于面向对象的语言,因此又可以避免类这个概念.
 * 因此,我们在javascript中,是否可以理解函数就是实例对象的元信息呢?如果
 * 可以的话,完全可以向java一样,把元信息存储在方法区中,如下图:
 */

/**
 * 然后,我们利用上面的简单例子在说明一下
 *
 */

function print(s){document.write(s+"<br/>")};
var prototypeObj1 = new PrototypeModel();
var prototypeObj2 = new PrototypeModel();
var prototypeObj3 = new PrototypeModel();

print(prototypeObj1.name+"---"+prototypeObj1.author+"---"+prototypeObj1.time);
print(prototypeObj2.name+"---"+prototypeObj2.author+"---"+prototypeObj2.time);
print(prototypeObj3.name+"---"+prototypeObj3.author+"---"+prototypeObj3.time);


其结果简单明了,



其内存模型,分析如下图



这样,我们可以把存放函数原型的区域称为函数区,这个区域是存放javascript内置函数原型和自定义函数原型的区域,当我们使用了内置函数或者自定义函数的时候,系统会

给每个实例对象(javascript中的函数实例就是对象)分配一个名称为prototype的属性,该属性也是一个引用类型(也许叫句柄更合适),但是该引用类型并不存放在栈中,而是保存在堆内存实例对象中的键值对中(因此,javascript中的对象其实就是由多个键值对组成的序列集合,),但是prototype属性中保存的是在函数区中的一个对象,该对象是Prototype的实例(类似于java中的Class实例),该实例保存着PrototypeModel函数的原型对象,因此我们在声明PrototypeModel函数后,不管我们new多少个PrototypeModel的实例,每个实例都会有prototype属性,该属性指向PrototypeModel原型,因此,可以断定javascript中的函数区是线程共享区域的,但是当我们为实例对象赋予属性的时候,情况就会发生变化,如下:

var prototypeObj4 = new PrototypeModel();
prototypeObj4.name = "felayman";
prototypeObj4.author  ="felay";
prototypeObj4.time = "1999-9-9";
print(prototypeObj4.name+"---"+prototypeObj4.author+"---"+prototypeObj4.time);


其结果如图:



这个时候,我们为prototypeObj4实例对象赋予的属性都存放在该实例对象的内存中,而不是存放在函数区中,因此是属于线程私有的,但是很不幸,我们赋予的属性名称和原型中的属性名称重叠了,因此实例对象原有属性值会区覆盖原型中的属性值.才会出现上述的内容.