Javascript 如何撤消Object.defineProperty调用?
ES5中有哪些选项可以撤消Javascript 如何撤消Object.defineProperty调用?,javascript,google-chrome,node.js,defineproperty,Javascript,Google Chrome,Node.js,Defineproperty,ES5中有哪些选项可以撤消defineProperty调用 请不要像Object.defineProperty=function(){}这样愚蠢的建议 下面的Object.defineProperty(Object.prototype,'should',{}) 做 和Object.defineProperty(Object.prototype,'should',{value:undefined}) 在V8中抛出一个 抛出 delete Object.prototype.should也应该一般来说
defineProperty
调用
请不要像Object.defineProperty=function(){}
这样愚蠢的建议
下面的Object.defineProperty(Object.prototype,'should',{})
做
和Object.defineProperty(Object.prototype,'should',{value:undefined})
在V8中抛出一个
抛出
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
});
您可以做的是删除或重新配置属性,或覆盖其值。如另一个答案中所述,如果要删除或重新配置,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
在访问器(get
/set
)和数据(value
)属性之间切换
要覆盖,请使用简单赋值。在这种情况下,需要将
可写
标志设置为真
。显然,这不适用于访问器属性。它甚至抛出了一个异常:
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!
});
请注意,
writeable
在使用defineProperty
时默认为false
,但在使用简单语法o.attr=val时默认为true
定义一个(以前不存在的)属性。有人能解释一下为什么我们不能通过给属性分配一个新值来覆盖或删除一个访问器
,就像这样obj.foo='new value'代码>?换句话说,为什么我们必须先删除该属性,或者重新配置它以消除该属性accessor@kapreski因为JavaScript访问器属性的工作方式不允许重新分配属性本身:当您尝试将值分配给访问器时,正确编程的JavaScript引擎将“陷阱”调用并将指定的值传递给访问器的setter函数(如果已定义),否则它将假定该属性根本不应该写入,并将抛出错误,如ECMAScript规范所示。将属性定义为访问器将删除默认的[[Get]]
和[[Set]]]
行为,以支持用户提供的行为。
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
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!
});