Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
320 views
in Technique[技术] by (71.8m points)

javascript - 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

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.

The delete operator is defined like this:

11.4.1 - The delete Operator

The production UnaryExpression : delete UnaryExpression is evaluated as follows:

So the result of using delete depends on [[Delete]]. Now let's see what [[Delete]] does:

8.12.7 - [[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:

  • 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.
  • Else if Throw, then throw a TypeError exception.
  • Return false.

Therefore, if the property is configurable, it should be deletable.

But wait, maybe Object.getOwnPropertyDescritor is a troll and says that a property is configurable, but [[Configurable]] is false. Let's see:

15.2.3.3 - Object.getOwnPropertyDescriptor ( O, P )

When the getOwnPropertyDescriptor function is called, the following steps are taken:

  • 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).

So it also uses [[GetOwnProperty]], like [[Delete]]. Maybe the troll is FromPropertyDescriptor?

8.10.4 FromPropertyDescriptor ( Desc )

When the abstract operation FromPropertyDescriptor is called with property descriptor Desc, the following steps are taken:

  • 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.

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?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

Effectively, configurable properties are deletable.

But there is a big problem: that only applies to native objects, but not to host objects.

As explained in 8.6.2 - Object Internal Properties and Methods,

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.

For those, [[GetOwnProperty]] must behave differently:

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.

In your example, form.elements is a HTMLFormControlsCollection instance defined by the HTML spec, so it's a host object.

Therefore, the situation is

  • 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.

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...