6

https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Object/definePropertyの状態:

構成可能:このプロパティ記述子のタイプが変更される可能性があり、プロパティが対応するオブジェクトから削除される可能性がある場合にのみtrue。デフォルトはfalse

だから、私は

var x = Object.defineProperty({}, "a", {
    value:true,
    writable:true,
    enumerable:true,
    configurable:false
});

x.a = falseこれで、などで遊ぶことができますfor(i in x)。ただし、記述子構成できないはずですが、実行できます。

Object.defineProperty(x, "a", {writable:true}); // others defaulting to false
Object.defineProperty(x, "a", {}); // everything to false
Object.freeze(x); // does the same to the descriptors

逆に、それらを再びtrueに設定するか、アクセサー記述子を定義しようとすると、エラーが発生するようになりました。正確には:Object.defineProperty: invalid modification of non-configurable property

記述子が構成不可能であると言われているのに、なぜ記述子を「ダウングレード」できるのですか?

4

1 に答える 1

16

まず、 が の場合でも、configurableからfalseに変更writableできます。が の場合に許可される属性の変更はこれだけです。この移行が許可されたのは、(最も注目すべき)配列のプロパティ ( を含む) を含むいくつかの組み込みプロパティが に指定されているためです。これは、以前の ECMAScript エディションの遺産です。からへの変更が妨げられた場合、アレイをフリーズすることは不可能です。truefalseconfigurablefalselengthArray.prototypewritable: true, configurable: falseconfigurable: falsewritabletruefalse

Object.definePropertyあなたが想定しているようにはうまくいきません。特に、プロパティ記述子の処理方法は、プロパティが既に存在するかどうかによって異なります。プロパティが存在しない場合、記述子はすべての属性の定義を提供することになっているため、記述子を使用してプロパティを作成する前に、記述子にない属性にはデフォルト値が割り当てられます。ただし、既存のプロパティの場合、記述子はプロパティの現在の属性設定からの差分変更のセットとして取得されます。記述子にリストされていない属性は変更されません。また、デルタ記述子に現在のプロパティ属性値と同じ値を持つ属性も変更なしと見なされます。したがって、以下はすべて合法です。

Object.defineProperty(x, "a", {writable:false}); // can always change writable to false.
                                                //others attributes, not changed
Object.defineProperty(x, "a", {});     // no attributes, so nothing changes
Object.freeze(x); // same as Object.defineProperty(x, "a", {writable:false});
Object.defineProperty(x, "a", {enumerable:true, configurable: false}); //no change, 
于 2012-03-23T16:49:00.623 に答える