/*
* 这里我是利用分析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实例对象赋予的属性都存放在该实例对象的内存中,而不是存放在函数区中,因此是属于线程私有的,但是很不幸,我们赋予的属性名称和原型中的属性名称重叠了,因此实例对象原有属性值会区覆盖原型中的属性值.才会出现上述的内容.
javascript内存模型分析猜想,布布扣,bubuko.com