【问题标题】:Why is this configurable property not deletable?为什么此可配置属性不可删除?
【发布时间】: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 运算符定义如下:

11.4.1 - The delete Operator

产生式 UnaryExpression : delete UnaryExpression 是 评价如下:

所以使用delete 的结果取决于[[Delete]]。现在让我们看看 [[Delete]] 做了什么:

8.12.7 - [[Delete]] (P, Throw)

O的[[Delete]]内部方法被属性调用时 名称​​P和布尔标志Throw,采取以下步骤:

  • desc 为调用属性名为 PO 的 [[GetOwnProperty]] 内部方法的结果。
  • 如果 descundefined,则返回 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 异常。
  • nameToString(P)。
  • desc 为使用参数 name 调用 O 的 [[GetOwnProperty]] 内部方法的结果。
  • 返回调用FromPropertyDescriptor(desc)的结果。

所以它也使用 [[GetOwnProperty]],如 [[Delete]]。也许巨魔是 FromPropertyDescriptor?

8.10.4 FromPropertyDescriptor ( Desc )

当抽象操作 FromPropertyDescriptor 被调用时 属性描述符Desc,采取以下步骤:

  • 如果 Descundefined,则返回 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


    【解决方案1】:

    实际上,可配置的属性是可删除的。

    但是有一个大问题:这只适用于native objects,不适用于host objects

    8.6.2 - Object Internal Properties and Methods 中所述,

    主机对象可以通过任何方式支持这些内部属性 依赖于实现的行为,只要它与 本文档中所述的特定主机对象限制。

    对于那些,[[GetOwnProperty]] 的行为必须不同:

    如果属性被描述为数据属性并且它可能返回 随着时间的推移不同的值,然后是 [[Writable]] 中的一个或两个 并且 [[Configurable]] 属性必须为 true,即使没有机制 更改值是通过其他内部方法公开的。

    在您的示例中,form.elements 是由 HTML 规范定义的 HTMLFormControlsCollection 实例,因此它是一个主机对象。

    所以情况是

    • 它有一个自定义的 [[GetOwnProperty]],表示属性 '0' 是可配置的,因为它的值可能会改变。
    • 它还有一个自定义的 [[Delete]] 不会删除该属性,即使 [[GetOwnProperty]] 说它是可配置的。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2011-08-31
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多