【发布时间】:2015-05-16 15:24:49
【问题描述】:
可配置的属性似乎是可删除的:
var o = {};
Object.defineProperty(o, 'prop', {
configurable: true,
value: 'val'
});
delete o.prop; // true
o.prop; // undefined
但它在以下情况下不起作用,至少在 Firefox 和 Chrome 上:
var form = document.createElement('form'),
input = document.createElement('input');
form.appendChild(input);
var elems = form.elements;
Object.getOwnPropertyDescriptor(form, 0)
.configurable; // true <────────────────────── !!!
delete elems[0]; // false │
elems[0]; // input │
(function(){ 'use strict'; // V
delete elems[0]; // TypeError: property 0 is non-configurable
})(); // and can't be deleted
但这似乎与规范相矛盾。
delete 运算符定义如下:
产生式 UnaryExpression :
deleteUnaryExpression 是 评价如下:
- 让 ref 成为评估 UnaryExpression 的结果。
- [...]
- 如果IsPropertyReference(ref) 是true,那么
- 返回在ToObject(GetBase(ref)) 上调用 [[Delete]] 内部方法的结果 GetReferencedName(ref) 和 IsStrictReference(ref) 作为 论据。
所以使用delete 的结果取决于[[Delete]]。现在让我们看看 [[Delete]] 做了什么:
8.12.7 - [[Delete]] (P, Throw)
当O的[[Delete]]内部方法被属性调用时 名称P和布尔标志Throw,采取以下步骤:
- 令 desc 为调用属性名为 P 的 O 的 [[GetOwnProperty]] 内部方法的结果。
- 如果 desc 为 undefined,则返回 true。
- 如果 desc.[[Configurable]] 为 true,则
- 从 O 中删除名称为 P 的自己的属性。
- 返回 true。
- 否则如果抛出,则抛出TypeError异常。
- 返回 false。
因此,如果属性是可配置的,它应该是可删除的。
但是等等,也许Object.getOwnPropertyDescritor 是一个巨魔,说属性是可配置的,但 [[Configurable]] 是 false。让我们看看:
15.2.3.3 - Object.getOwnPropertyDescriptor ( O, P )
当 getOwnPropertyDescriptor 函数被调用时, 采取以下步骤:
- 如果 Type(O) 不是 Object,则抛出 TypeError 异常。
- 让 name 为 ToString(P)。
- 令 desc 为使用参数 name 调用 O 的 [[GetOwnProperty]] 内部方法的结果。
- 返回调用FromPropertyDescriptor(desc)的结果。
所以它也使用 [[GetOwnProperty]],如 [[Delete]]。也许巨魔是 FromPropertyDescriptor?
8.10.4 FromPropertyDescriptor ( Desc )
当抽象操作 FromPropertyDescriptor 被调用时 属性描述符Desc,采取以下步骤:
- 如果 Desc 是 undefined,则返回 undefined。
- 让 obj 成为创建新对象的结果,就好像通过表达式 new Object() 其中 Object 是标准内置 -在 具有该名称的构造函数。
- ...
- 使用参数“
configurable”,Property Descriptor {[[Value]]调用obj的[[DefineOwnProperty]]内部方法: Desc.[[Configurable]], [[Writable]]: true, [[Enumerable]]: true, [[Configurable]] : true} 和 false。- 返回obj。
所以不,它也不是巨魔。属性描述符的configurable 属性设置为 [[Configurable]] 值。
那么,一个可配置的属性怎么可能不能被删除呢?
【问题讨论】:
标签: javascript properties language-lawyer ecma262