ECMAScript 5:为什么某些属性属性继承而其他属性不是?

时间:2014-07-04 22:05:02

标签: javascript properties attributes prototypal-inheritance

似乎ECMAScript 5属性属性是继承的,而其他属性则不是。根据Google Chrome,Safari和Firefox中的简单实验,enumerablewritable似乎是从原型继承的,但configurable不是。考虑ab的原型,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 aa的属性属性的行为方式相同吗?”:

b

用于测试的代码:

Object {enumerable: true, configurable: false, writable: true}

1 个答案:

答案 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原型链的某处,不会影响此过程;即可配置性继承