为什么此可配置属性不可删除
Why is this configurable property not deletable?
属性似乎是可删除的:
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
运算符定义如下:
11.4.1 - 删除运算符
生产 UnaryExpression :
delete
UnaryExpression 是 评估如下:
- 让 ref 成为评估 UnaryExpression 的结果。
- [...]
- 如果 IsPropertyReference(ref) 为真,则
- 返回在 ToObject(GetBase(ref)) 上调用 [[Delete]] 内部方法的结果,该方法提供 GetReferencedName(ref) 和 IsStrictReference(ref) 作为 参数。
因此,使用 delete
的结果取决于 [[删除]]。现在让我们看看 [[删除]] 的作用:
8.12.7 - [[删除]] (P, 投掷)
当使用属性调用 O 的 [[Delete]] 内部方法时 名称 P 和布尔标志抛出,执行以下步骤:
- 让 desc 是调用属性名称为 P 的 O 的 [[GetOwnProperty]] 内部方法的结果。
- 如果未定义desc ,则返回 true。
- 如果描述。[[可配置]] 为真,则
否则,如果抛出
- 从 O 中删除名为 P 的自有属性。
- 返回 true。
- ,则抛出TypeError 异常。
- 返回假。
因此,如果属性是可配置的,则它应该是可删除的。
但是等等,也许Object.getOwnPropertyDescritor
是一个巨魔,说一个属性是可配置的,但[[可配置]]是假的。我看看:
15.2.3.3 - Object.getOwnPropertyDescriptor ( O, P )
当调用 getOwnPropertyDescriptor 函数时, 将采取以下步骤:
- 如果 Type(O) 不是 Object 则引发 TypeError 异常。
- 让 name 为 ToString(P)。
- 让 desc 是使用参数名称调用 O 的 [[GetOwnProperty]] 内部方法的结果。
- 返回调用 FromPropertyDescriptor(desc) 的结果。
所以它也使用[[GetOwnProperty]],如[[Delete]]。也许巨魔是FromPropertyDescriptor?
8.10.4 FromPropertyDescriptor ( desc )
当调用抽象操作 FromPropertyDescriptor 时 属性描述符 Desc,将执行以下步骤:
- 如果 Desc 未定义,则返回未定义。
- 让 obj 是创建新对象的结果,就像通过表达式 new Object() 一样,其中 Object 是标准的内置 具有该名称的构造函数。
- 。
- 调用 obj 的 [[DefineOwnProperty]] 内部方法,参数 "
configurable
",属性描述符 {[[Value]]: 德克。[[可配置]]、[[可写]]:真、[[可枚举]]:真、[[可配置]]:真}和假。- 返回对象。
所以不,它也不是巨魔。属性描述符的 configurable
属性设置为 [[可配置]] 值。
那么,为什么不能删除可配置属性呢?
实际上,可配置的属性是可删除的。
但是有一个大问题:这仅适用于本机对象,而不适用于主机对象。
如 8.6.2 - 对象内部属性和方法中所述,
主机对象可能支持这些内部属性与任何 依赖于实现的行为,只要它符合 本文档中所述的特定主机对象限制。
对于这些,[[GetOwnProperty]]的行为必须不同:
如果属性被描述为数据属性,并且它可能会返回 随时间推移的不同值,然后是 [[可写]] 中的一个或两个 和 [[可配置]] 属性必须为 true,即使没有机制 更改值通过其他内部方法公开。
在您的示例中,form.elements
是由 HTML 规范定义的HTMLFormControlsCollection
实例,因此它是一个主机对象。
因此,情况是
- 它有一个自定义的[[GetOwnProperty]],它说属性
'0'
是可配置的,因为它的值可能会改变。 - 它还有一个自定义的[[删除]],即使[[GetOwnProperty]]说它是可配置的,也不会删除该属性。
- 在不知道深度或父属性的情况下从对象中删除属性
- 如何从对象中删除属性
- 使用jQuery添加和删除属性
- 为什么没有从数组中存在的对象中删除属性
- 删除属性后刷新DOM,而不象chrome那样刷新页面
- Jquery 在当前之前从元素中删除属性
- 在窗口调整大小时删除属性
- 如何从使用 jquery 添加的项中删除属性
- 从 JavaScript 中的 XAML 元素中删除属性
- 主干模型.未设置不删除属性
- 无法在单击时添加/删除属性
- 从主干.js模型中删除属性
- 如果选中复选框,请删除属性
- jQuery单击功能可从元素中删除属性并在单独单击时恢复属性
- 如果找到特定类,如何添加和删除属性
- 如何使用 Javascript 从 DOM 元素中删除属性
- 从 Javascript 对象中删除属性
- 量角器未知错误,从 DOM 中删除属性
- 如何使用jquery onchange事件在HTML中添加和删除属性
- 如何从任何级别的嵌套javascript对象中删除属性