v8 是Google德国团队用c++开发的一个javascript 引擎。但凡需要解释并执行javascript代码的地方,都可以使用v8引擎。比如客户端chrome浏览器和服务端nodejs都使用v8引擎来解析执行javascript代码。
最初设计v8是用来提高在web浏览器内执行javascript的性能。为此,v8弃用interpreter,在执行时用JIT (Just-In-Time)编译器将javascript代码直接翻译成机器码(machine code)。SpiderMonkey和 Rhino (Mozilla)引擎同样使用jit编译器,不同的是,v8省去了中间产生bytecode或者intermediate code 的过程。
hidden class
javascript对象的创建是基于原型(prototype based)的克隆过程(clone process),没有‘类‘这个概念。加之有动态语言的特性,既一个对象的属性可以动态添加或者删除。如何快速查找对象属性呢?一般的javascript引擎使用类字典数据结构(基于哈希函数的associated array)存储对象属性值的内存位置。相比静态语言比如java,获取对象属性比较耗时。因为java的对象属性在运行时在类中已经固定位置,并且不能添加或者删除。也就是说,通过对象指针,再加之一些的偏移量,就可以找到对象属性的地址。
既然使用字典数据结构动态查找属性不高效,那么v8引擎使用了不同的方法:hidden class。hidden class的查找属性的工作原理同java的class类似,对象的内存布局固定不变。
看这几行代码:
function Point(x, y) {
this.x = x;
this.y = y;
}
var p1 = new Point(1, 2);
调用new Point()
时候,v8创建一个hidden class,C0。此时C0为空。当执行完this.x = x;
这句后,v8创建一个新的hidden class,C1。C1基于C0创建,C1描述了属性x的位置(根据对象指针加上偏移量)。这里,x的偏移量为0,这就意味着,在对象指针所指地址的第一段偏移存储的就是属性x的值。
接着this.y = y;
,基于C1创建新hidden class,C2。
此时,hidden class的转换路径是 C0 > C1 > C2。
优化js代码
- 将对象的所有属性一次性全部定义在构造函数中,不要在实例化对象后动态添加属性。