Javascript ECMAScript 5:为什么有些属性是继承的,而其他属性不是继承的?

Javascript ECMAScript 5:为什么有些属性是继承的,而其他属性不是继承的?,javascript,properties,attributes,prototypal-inheritance,Javascript,Properties,Attributes,Prototypal Inheritance,ECMAScript 5属性属性似乎是继承的,而其他属性则不是。基于Google Chrome、Safari和Firefox中的一个简单实验,似乎可枚举和可写是从原型继承而来的,但不可配置。考虑A是B的原型,A定义属性X,而B不定义。如果x不可写,那么b不能用=(如果允许的话)重写x的值,这将只更改b的x,而不是标记为不可写的x的a。但是,即使x既不可配置也不可写,b也可以使用Object.definePropertyb、'x',重写x的值。。。对于a:Object.defineProperty

ECMAScript 5属性属性似乎是继承的,而其他属性则不是。基于Google Chrome、Safari和Firefox中的一个简单实验,似乎可枚举和可写是从原型继承而来的,但不可配置。考虑A是B的原型,A定义属性X,而B不定义。如果x不可写,那么b不能用=(如果允许的话)重写x的值,这将只更改b的x,而不是标记为不可写的x的a。但是,即使x既不可配置也不可写,b也可以使用Object.definePropertyb、'x',重写x的值。。。对于a:Object.definePropertya,'x',…,这将失败,因为a的'x'是不可配置的

我看不到任何东西可以解释这一点,也许它就在那里,但我找不到它。这种不一致的行为是故意的吗

测试输出答案a和b的属性属性的行为是否相同

对象{可枚举:true,可配置:false,可写:true} 用于测试的代码:

函数isEnumerablep,o{ 对于o中的var键{ 如果键===p{ 返回true; } 返回false; } } 函数为配置P、d、o{ 试一试{ Object.defineProperty o,p,d; 返回true; }抓住e{ 返回false; } } 函数是可写的p,v,o{ 如果o[p]==v{ 抛出“错误:isWritable不能使用相同的值”; } o[p]=v; 返回o[p]==v; } 函数继承属性 父生成器, propertyName, 不同的描述者, 不同价值{ var parent,child,rtn={}; var fns={ “可枚举”:isEnumerable.bindthis,propertyName, “可配置”:isConfigurable.bind 这 propertyName, 不同的描述者, “可写”:isWritable.bindthis、propertyName、DifferentitValue }; 对于fns中的var键{ 父项=父项生成器; child=Object.createparent; rtn[key]=fns[key]父项===fns[key]子项; } 返回rtn; } var propertyName='x'; var-starterProperties={}; 启动器属性[propertyName]={ “可写”:false, “可配置”:false, “可枚举”:false, “值”:“foo” }; 变量差异描述器={ “可写”:false, “可配置”:false, “可枚举”:false, “值”:“条” }; var差异值='baz'; var parentGenerator=函数{ 返回Object.createObject.prototype,初始属性; }; window.console.loginheritedAttributes 父生成器, propertyName, 不同的描述者, 不同价值 ;
这并不能回答为什么。我怀疑答案是为什么,因为这是标准所说的。尽管如此,这里还是有一些相关的链接、摘录和标准的释义。谢谢你为我指明了正确的方向

可枚举 文件还强调:

枚举对象的属性包括枚举 原型的特性,以及原型的原型,以及 以此类推,递归地;但是,如果 它是“阴影”的,因为原型链中以前的某个对象 具有同名的属性。[[Enumerable]]的值 在确定属性是否为 原型对象被原型上的前一个对象遮挡 链子

因此,可枚举性是继承的

可写 属性赋值调用内部方法,该方法从检查的返回值开始。当属性是值而不是getter+setter时,[[CanPut]]将按以下顺序检查属性属性:

obj的x属性的可写属性 obj的可扩展属性 对于从obj原型到但不包括null的每个原型: 原型的可扩展属性 prototype的x属性的可写属性 如果定义了这些属性中的任何一个,则返回其值。因此,即使其他属性丢失,obj原型链中的某个不可写属性也会导致obj上的赋值失败;i、 例如,可写性是继承的

可配置
Object.defineProperty调用内部方法,这相当复杂。通常,此方法只涉及obj的可扩展属性和obj当前自己的x属性(如果存在)的可配置属性。因此,obj原型链中某个位置的不可配置属性x不会影响该过程;i、 例如,可配置性不是继承的。

看看[[CanPut]]:这个函数测试您是否可以将b.x=1这样的值放入对象中。如您所见,原型也将进行检查。据我所知,只要一个对象是[[可扩展的]],你就可以向它添加新的属性,比如使用defineProperty。我明白了。所以这种不对称的部分原因是赋值和枚举分别依赖于属性的可写属性和可枚举属性 在定义属性的任何对象上。但是,defineProperty的成功取决于相关对象的[[Extensible]],以及相关对象上属性的可配置属性,而不是其原型。准确吗?
for (var key in obj) { ... }
obj.x = a;
Object.defineProperty(obj, 'x', { 'value': a, ... });