如果我们创建新的原型属性,对象会改变它的隐藏类吗?
Will the object change its hidden class if we create new prototype properties?
在V8中,当添加新属性时,对象会更改其隐藏类。
function Point(x, y) {
this.x = x; // This will create new hidden class
this.y = y; // This too
}
我的问题很简单,这会创建一个新的隐藏类吗?
Point.prototype.z = null;
我问这个问题是因为在我读过的编码风格指南中,他们说我们应该通过创建原型来声明类属性,而不是在构造函数中分配它们。这也将帮助我们轻松地用JSDoc记录它们。
答案是是:一个新的隐藏类将被创建。然而,重要的是要理解,将改变其隐藏类的是原型对象本身,而不是Point构造函数创建的对象。
任何对象都有一个附加的隐藏类。让我们看一下代码
var o = new Point();
o.z = 0; // (1)
Point.prototype.zz = 0; // (2)
在任何给定时刻,任何对象都有一个隐藏类,这意味着o
, o.__proto__
, o.__proto__.__proto__
有一个与它们相关联的独特的隐藏类。
当你给对象添加一个新属性时,改变的只是该对象的隐藏类。如果你改变了原型的隐藏类,共享原型的对象的隐藏类不会改变。由于我们不期望对象X
的隐藏类完全描述其整个原型链中任何对象的布局,因此不需要进行这样的更改,其隐藏类仅描述X
和X
的布局。此外,实现这种向下传播是不可行的:这将要求VM在原型和所有相关对象之间保持向后链接:能够在任何时候为对象X
枚举具有Y.__proto__ === X
的所有对象Y
。
对于上面的代码,这意味着语句(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();
有时被推荐,这是一个性能反模式,因为o1
/o2
和Point.prototype
的隐藏类是断开连接的。在(3)
赋值会改变o1
的隐藏类,即使o1.__proto__
已经有了属性z
。对象o1
和o2
将最终具有不同的隐藏类,这将导致所有使用它们的代码都多态并惩罚性能。此外,o1
最终会比在构造函数中添加z
使用更多的空间,因为z
将存储在对象外属性存储中。
相关文章:
- 输入字段值属性不会改变,除非type=“”;隐藏”;
- Jquery隐藏/显示取决于复选框改变的值
- JQuery改变输入类型隐藏值
- 只有Javascript -改变图像悬停在隐藏的单选按钮
- 多个显示/隐藏改变文本
- 如果我们创建新的原型属性,对象会改变它的隐藏类吗?
- 溢出未隐藏,但不透明度改变
- 如何隐藏Safari的工具栏时,方向改变为横向模式
- Javascript:根据隐藏变量值改变按钮文本
- 在一个溢出:隐藏的包含元素上改变焦点,移动它,但造成不明显的差异
- jQuery显示/隐藏选项从一个选择下拉菜单,当其他选择下拉菜单的选项被选中,而不改变当前选项
- Jquery显示/隐藏按钮来改变工具提示
- 如何改变滚动条样式或隐藏滚动条在浏览器通过javascript或css
- 下拉隐藏图像在改变javascript
- 缩放级别改变时如何显示/隐藏标记
- 隐藏表单字段值没有真正改变
- 当隐藏输入改变时触发onchange事件
- 我有一个输入,它的's类型设置为隐藏,我需要改变它的's类型为文本.我似乎无法弄清楚这一点,或者它是否可
- Jquery通过隐藏属性和值比较改变span值
- 隐藏移动Chrome上的键盘;t改变车窗高度