Tru*_*gDQ 11 javascript prototype v8 internals
在V8中,对象在添加新属性时更改其隐藏类.
function Point(x, y) {
this.x = x; // This will create new hidden class
this.y = y; // This too
}
Run Code Online (Sandbox Code Playgroud)
我的问题很简单,这会创建新的隐藏类吗?
Point.prototype.z = null;
Run Code Online (Sandbox Code Playgroud)
我问这个问题是因为在我读过的编码风格指南中,他们说我们应该通过创建原型来声明类属性,而不是在构造函数中赋值.这也有助于我们使用JSDoc轻松记录它们.
非常感谢.
答案是肯定的:将创建一个新的隐藏类.然而,重要的是要理解原型对象本身将改变其隐藏类,而不是Point构造函数创建的对象.
任何对象都附加了一个隐藏类.让我们看看代码
var o = new Point();
o.z = 0; // (1)
Point.prototype.zz = 0; // (2)
Run Code Online (Sandbox Code Playgroud)
在任何时刻任何对象有一个隐藏的类,这意味着o,o.__proto__,o.__proto__.__proto__有一个与之相关的独特的隐藏类.
向对象添加新属性时,它只是该对象的隐藏类才会更改.如果更改原型的隐藏类,则共享该原型的隐藏对象类不会更改.不需要进行这样的更改,因为我们不希望对象的隐藏类X完全描述其整个原型链中任何对象的布局,其隐藏类描述了布局X和X单独.此外,实现这种向下传播是不可行的:这需要VM维护原型和所有相关对象之间的后向链接:能够在任何时刻使对象X枚举所有Y具有的对象Y.__proto__ === X.
对于上面的代码意味着语句(1)的变化仅隐藏类的o和声明(2)的变化仅隐藏类的Point.prototype(这是相同的对象o.__proto__),但不的o本身.
此外,如果您考虑这样的代码:
Point.prototype.z = 0; // Initial value
var o1 = new Point();
o1.z = 11; // (3)
var o2 = new Point();
Run Code Online (Sandbox Code Playgroud)
这有时是推荐的,这是一个性能反模式正是因为o1/ o2和隐藏的类Point.prototype被断开了.即使已经拥有属性,分配(3)也会改变隐藏类.对象并最终会有不同的隐藏类,这将导致使用它们的所有代码变为多态并惩罚性能.此外,最终将使用比在构造函数中添加的情况更多的空间,因为它将存储在对象外属性存储中.o1o1.__proto__zo1o2o1zz
| 归档时间: |
|
| 查看次数: |
684 次 |
| 最近记录: |