似乎ECMAScript 5属性属性是继承的,而其他属性则不是。根据Google Chrome,Safari和Firefox中的简单实验,enumerable
和writable
似乎是从原型继承的,但configurable
不是。考虑a
是b
的原型,a
定义属性x
(但b
没有)。如果x
不可写,则b
无法覆盖x
=
的值,如果允许,则只会更改b
的{{1}} x
1}},而不是a
(标记为不可写的x
)。但是,即使x
既不可配置也不可写,b
可能会覆盖x
Object.defineProperty(b, 'x', ...)
的值(a
会失败:{{1}因为Object.defineProperty(a, 'x', ...)
的'x'不可配置)。
我在standard中没有看到任何解释这一点的内容(也许它就在那里,但我找不到它)。是否存在这种不一致的行为?
测试输出(答案“do a
和a
的属性属性的行为方式相同吗?”:
b
用于测试的代码:
Object {enumerable: true, configurable: false, writable: true}
答案 0 :(得分:0)
这不回答“为什么”。我怀疑“为什么”的答案是“因为这就是标准所说的”。不过,这里有一些标准的相关链接,摘录和解释。感谢basilikum让我指出了正确的方向。
for (var key in obj) { ... }
for-in statement文档说明(强调添加):
枚举对象的属性包括枚举 它的原型的属性,原型的原型,和 等等,递归地;但如果是,则不会枚举原型的属性 它是“阴影”,因为原型链中的某些先前对象 有一个同名的财产。 [[可枚举]]的值 在确定a的属性时不考虑属性 原型对象被原型上的前一个对象遮蔽 链
因此,可枚举性是继承的。
obj.x = a;
属性赋值调用内部方法[[Put]],该方法首先检查[[CanPut]]的返回值。当属性是值而不是getter + setter时,[[CanPut]]将按以下顺序检查属性属性:
obj
的{{1}}媒体资源x
属性writable
的{{1}}属性obj
的原型到(但不包括)extensible
的每个原型:
obj
属性null
属性的extensible
属性如果定义了这些属性中的任何一个,则返回其值。因此,即使缺少其他属性,x
原型链下方的不可写属性也会导致writable
上的赋值失败;即可写性是继承的。
obj
obj
调用内部方法[[DefineOwnProperty]],这是相当复杂的。 一般情况下,此方法仅涉及Object.defineProperty(obj, 'x', { 'value': a, ... });
的{{1}}属性以及Object.defineProperty
当前extensible属性。 >拥有 obj
属性(如果存在)。因此,不可配置的属性configurable
,在obj
原型链的某处,不会影响此过程;即可配置性不继承。