首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何撤消Object.defineProperty调用?

如何撤消Object.defineProperty调用?
EN

Stack Overflow用户
提问于 2011-08-22 05:11:54
回答 1查看 16.6K关注 0票数 46

Fiddle

代码语言:javascript
复制
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', {})

not work可以吗?

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

在V8中引发Uncaught TypeError: Cannot redefine property: defineProperty

代码语言:javascript
复制
Object.defineProperty(Object.prototype, 'should', { 
    set: function() {},
    get: function() { return undefined; }
});

抛出same error

delete Object.prototype.should也叫does not work

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2011-08-22 15:20:48

通常,您不能撤消defineProperty调用,因为没有撤消堆栈之类的东西。JS引擎不跟踪以前的属性描述符。

例如,

代码语言:javascript
复制
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

代码语言:javascript
复制
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并传递不同的描述符:

代码语言:javascript
复制
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。显然,这不适用于访问器属性。它甚至抛出了一个异常:

代码语言:javascript
复制
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,但当您使用简单语法o.attr = val;定义一个(以前不存在的)属性时,则默认为true

票数 50
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/7141210

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档