48

フィドル

var Assertion = function() {
    return { "dummy": "data" };    
}

Object.defineProperty(Object.prototype, 'should', {
  set: function(){},
  get: function(){
    return new Assertion(this);
  }
});

// Insert magic here.

// This needs to be false
console.log(({}).should === undefined);

defineProperty呼び出しを元に戻すために、ES5 にはどのようなオプションがありますか?

ばかげた提案はありませんObject.defineProperty = function() { }

以下Object.defineProperty(Object.prototype, 'should', {})

動作しませ

Object.defineProperty(Object.prototype, 'should', { value: undefined })

Uncaught TypeError: Cannot redefine property: definePropertyV8 でaをスローします。

Object.defineProperty(Object.prototype, 'should', { 
    set: function() {},
    get: function() { return undefined; }
});

同じエラーをスローします

delete Object.prototype.shouldまた、動作しません

4

1 に答える 1

51

defineProperty一般に、元に戻すスタックなどがないため、呼び出しを元に戻すことはできません。JSエンジンは、以前の属性記述子を追跡しません。

例えば、

Object.defineProperty(Object.prototype, 'foo', {
    configurable: true,
    value: 1,
    enumerable: false
});
Object.defineProperty(Object.prototype, 'foo', {
    get: function () {
        alert('You cannot revert me');
        return 2;
    },
    enumerable: true
});

できることは、属性を削除または再構成するか、その値を上書きすることです。他の回答で述べたように、削除または再構成する場合configurableはフラグが必要です。trueプロパティがで定義されると、フラグconfigurable:falseを変更することはできません。configurable


属性を削除するには(これはおそらくあなたがやりたいことです)、以下を使用しますdelete

Object.defineProperty(Object.prototype, 'foo', {
    configurable: true, // defaults to false
    writable: false,
    value: 1
});
delete Object.prototype.foo;
console.log(Object.prototype.hasOwnProperty('foo')); // false

再構成するには、definePropertyもう一度使用して、別の記述子を渡します。

Object.defineProperty(Object.prototype, 'foo', {
    configurable: true,
    get: ...
    set: ...
});
Object.defineProperty(Object.prototype, 'foo', {
    value: undefined
});
console.log({}.foo); // undefined
console.log(Object.prototype.hasOwnProperty('foo')); // true

このサンプルに示されているように、アクセサ( / )プロパティとデータ( )プロパティdefinePropertyを切り替えるために使用できます。getsetvalue


上書きするには、単純な割り当てを使用します。この場合、writableフラグはである必要がありますtrue。明らかに、これはアクセサプロパティでは機能しません。それも例外をスローします:

Object.defineProperty(Object.prototype, 'foo', {
    configurable: true,
    value: 1,
    writable: true // defaults to false
});
Object.prototype.foo = undefined;
console.log(Object.prototype.foo); // undefined
console.log(Object.prototype.hasOwnProperty('foo')); // true

Object.defineProperty(Object.prototype, 'foo', {
    get: function () {
        return 1;
    },
    writable: true // JS error!
});

writableデフォルトではfalse、を使用する場合definePropertytrue、単純な構文o.attr = val;を使用して(以前は存在しなかった)プロパティを定義する場合に注意してください。

于 2011-08-22T07:20:47.597 に答える