如何撤消Object.defineProperty调用?

小提琴

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); 

我有什么select在ES5中撤销defineProperty调用?

没有愚蠢的build议像Object.defineProperty = function() { }请。

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

不起作用

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

抛出一个Uncaught TypeError: Cannot redefine property: defineProperty在V8中Uncaught TypeError: Cannot redefine property: defineProperty

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

抛出同样的错误

delete Object.prototype.should也不起作用

一般来说,你不能撤销一个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 }); 

你可以做的是删除重新configuration一个属性,或覆盖它的值。 正如在另一个答案中提到的,如果要删除或重新configuration,可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 

要重新configuration, defineProperty再次使用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在访问器( get / set )和数据( value )属性之间切换。


要覆盖,请使用简单的赋值。 在这种情况下,您需要writable标志为true 。 显然这不适用于访问器属性。 它甚至会抛出一个exception:

 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! }); 

请注意,当您使用defineProperty时, writable默认值为false ,但当您使用简单语法时为true o.attr = val; 定义一个(以前不存在的)财产。