javascript 如何撤消 Object.defineProperty 调用?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/7141210/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How do I undo a Object.defineProperty call?
提问by Raynos
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);
What options do I have in ES5 to undo a defineProperty
call ?
在 ES5 中有哪些选项可以撤消defineProperty
呼叫?
No silly suggestions like Object.defineProperty = function() { }
please.
请不要愚蠢的建议Object.defineProperty = function() { }
。
The following Object.defineProperty(Object.prototype, 'should', {})
下列 Object.defineProperty(Object.prototype, 'should', {})
does not work
确实不工作
and Object.defineProperty(Object.prototype, 'should', { value: undefined })
和 Object.defineProperty(Object.prototype, 'should', { value: undefined })
Throws a Uncaught TypeError: Cannot redefine property: defineProperty
in V8
Uncaught TypeError: Cannot redefine property: defineProperty
在 V8 中抛出一个
Object.defineProperty(Object.prototype, 'should', {
set: function() {},
get: function() { return undefined; }
});
Throws the same error
抛出同样的错误
delete Object.prototype.should
also does not work
delete Object.prototype.should
也不起作用
回答by user123444555621
In general, you can't undo a defineProperty
call, since there's no undo stack or something. The JS engine does not keep track of previous attribute descriptors.
通常,您无法撤消defineProperty
调用,因为没有撤消堆栈或其他东西。JS 引擎不会跟踪以前的属性描述符。
For example,
例如,
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
});
What you can do is removeor reconfigurean attribute, or overwriteits value. As mentioned in the other answer, the configurable
flag is required to be true
if you want to remove or reconfigure.
Once a property is defined with configurable:false
, you cannot change the configurable
flag.
您可以做的是删除或重新配置属性,或覆盖其值。如另一个答案中所述,如果您想删除或重新配置,configurable
则需要该标志true
。一旦使用 定义了属性configurable:false
,就无法更改configurable
标志。
To remove an attribute (this is supposedly what you want to do), use delete
:
要删除属性(这应该是您想要做的),请使用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
To reconfigure, use defineProperty
again and pass a different descriptor:
要重新配置,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
As shown in this sample, you can use defineProperty
to switch between accessor (get
/set
) and data (value
) properties.
如本示例所示,您可以使用defineProperty
在访问器 ( get
/ set
) 和数据 ( value
) 属性之间切换。
To overwrite, use simple assignment. In this case, you need the writable
flag to be true
. Obviously this does not work with accessor properties. It even throws an exception:
要覆盖,请使用简单分配。在这种情况下,您需要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!
});
Note that writable
defaults to false
when you use defineProperty
, but true
when you use the simple syntax o.attr = val;
to define a (previously not existing) property.
请注意,当您使用时writable
默认为,但当您使用简单语法定义(以前不存在的)属性时。false
defineProperty
true
o.attr = val;