为什么不能删除此可配置属性? [英] Why is this configurable property not deletable?
问题描述
可配置的属性似乎是可删除的:
Configurable properties seem to be deletable:
var o = {};
Object.defineProperty(o, 'prop', {
configurable: true,
value: 'val'
});
delete o.prop; // true
o.prop; // undefined
但是在以下情况下,至少在Firefox和Chrome上它不起作用:
But it doesn't work in the following case, at least on Firefox and 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
但这似乎与规范相矛盾.
But this seems to contradict the spec.
delete
运算符的定义如下:
生产 UnaryExpression :delete
UnaryExpression 是
评估如下:
The production UnaryExpression : delete
UnaryExpression is
evaluated as follows:
- 让 ref 为评估 UnaryExpression 的结果.
- [...]
- 如果 IsPropertyReference ( ref )为 true ,然后
- 返回在 ToObject ( GetBase ( ref ))提供 GetReferencedName ( ref )和 IsStrictReference ( ref )作为这 争论.
- Let ref be the result of evaluating UnaryExpression.
- [...]
- If IsPropertyReference(ref) is true, then
- Return the result of calling the [[Delete]] internal method on ToObject(GetBase(ref)) providing GetReferencedName(ref) and IsStrictReference(ref) as the arguments.
因此,使用
delete
的结果取决于[[Delete]].现在,让我们看看[[Delete]]的作用:So the result of using
delete
depends on [[Delete]]. Now let's see what [[Delete]] does:使用属性调用 O 的[[Delete]]内部方法时 名称 P 和布尔标志 Throw ,请执行以下步骤:
When the [[Delete]] internal method of O is called with property name P and the Boolean flag Throw, the following steps are taken:
- 让 desc 是调用属性名称为 P 的 O 的[[GetOwnProperty]]内部方法的结果.
- 如果 desc 是未定义,则返回 true .
- 如果 desc .[[Configurable]]为 true ,则
- 从 O 中删除名称为 P 的自有属性.
- 返回 true .
- Let desc be the result of calling the [[GetOwnProperty]] internal method of O with property name P.
- If desc is undefined, then return true.
- If desc.[[Configurable]] is true, then
- Remove the own property with name P from O.
- Return true.
因此,如果该属性是可配置的,则应将其删除.
Therefore, if the property is configurable, it should be deletable.
但是,等等,也许
Object.getOwnPropertyDescritor
是一个巨魔,并说一个属性是可配置的,但是[[Configurable]]是 false .让我们看看:But wait, maybe
Object.getOwnPropertyDescritor
is a troll and says that a property is configurable, but [[Configurable]] is false. Let's see:调用 getOwnPropertyDescriptor 函数时, 采取以下步骤:
When the getOwnPropertyDescriptor function is called, the following steps are taken:
- 如果类型( O )不是对象抛出 TypeError 异常.
- 让 name 为 ToString ( P ).
- 让 desc 是使用参数 name 调用 O 的[[GetOwnProperty]]内部方法的结果.
- 返回调用 FromPropertyDescriptor ( desc ).
- If Type(O) is not Object throw a TypeError exception.
- Let name be ToString(P).
- Let desc be the result of calling the [[GetOwnProperty]] internal method of O with argument name.
- Return the result of calling FromPropertyDescriptor(desc).
因此,它也使用[[GetOwnProperty]],例如[[Delete]].也许巨魔是FromPropertyDescriptor?
So it also uses [[GetOwnProperty]], like [[Delete]]. Maybe the troll is FromPropertyDescriptor?
使用调用抽象操作FromPropertyDescriptor时 属性描述符 Desc ,请执行以下步骤:
When the abstract operation FromPropertyDescriptor is called with property descriptor Desc, the following steps are taken:
- 如果 Desc 是 undefined ,则返回 undefined .
- 让 obj 是创建新对象的结果,就像通过表达式 new Object()一样,其中 Object 是标准的内置对象,在 具有该名称的构造函数.
- ...
- 使用参数"
configurable
",
- If Desc is undefined, then return undefined.
- Let obj be the result of creating a new object as if by the expression new Object() where Object is the standard built-in constructor with that name.
- ...
- Call the [[DefineOwnProperty]] internal method of obj with arguments "
configurable
", Property Descriptor {[[Value]]: Desc.[[Configurable]], [[Writable]]: true, [[Enumerable]]: true, [[Configurable]]: true}, and false. - Return obj.
所以不,它也不是一个巨魔.属性描述符的
configurable
属性设置为[[Configurable]]值.So no, it is not a troll neither. The
configurable
property of the property descriptor is set to the [[Configurable]] value.那么,怎么可能无法删除可配置属性?
How is it possible, then, that a configurable property can't be deleted?
推荐答案
有效地,可配置属性是可删除的.
Effectively, configurable properties are deletable.
But there is a big problem: that only applies to native objects, but not to host objects.
主机对象可以通过任何方式支持这些内部属性 与实现相关的行为,只要它与 本文档中所述的特定主机对象限制.
Host objects may support these internal properties with any implementation-dependent behaviour as long as it is consistent with the specific host object restrictions stated in this document.
对于这些,[[GetOwnProperty]]的行为必须与众不同:
For those, [[GetOwnProperty]] must behave differently:
如果将属性描述为数据属性,则可能会返回 随时间变化的不同值,则[[Writable]]之一或全部 和[[Configurable]]属性必须为 true ,即使没有机制 更改值是通过其他内部方法公开的.
If a property is described as a data property and it may return different values over time, then either or both of the [[Writable]] and [[Configurable]] attributes must be true even if no mechanism to change the value is exposed via the other internal methods.
在您的示例中,
form.elements
是HTML规范定义的HTMLFormControlsCollection
实例,因此它是宿主对象.In your example,
form.elements
is aHTMLFormControlsCollection
instance defined by the HTML spec, so it's a host object.因此,情况是
- 它具有一个自定义[[GetOwnProperty]],它表示属性
'0'
是可配置的,因为其值可能会更改. - 它还有一个自定义[[Delete]],即使[[GetOwnProperty]]声明它是可配置的,它也不会删除该属性.
- It has a custom [[GetOwnProperty]] which says that the property
'0'
is configurable because its value may change. - It also has a custom [[Delete]] which doesn't delete the property, even if [[GetOwnProperty]] says it's configurable.
这篇关于为什么不能删除此可配置属性?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!