如何撤消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;
定义一个(以前不存在的)财产。