javascript - 如何撤消 Object.defineProperty 调用?

标签 javascript google-chrome node.js defineproperty

Fiddle

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

在 ES5 中有哪些选项可以撤消 defineProperty 调用?

请不要像 Object.defineProperty = function() { } 这样愚蠢的建议。

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

是否 not work

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

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

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

抛出 same error

delete Object.prototype.should 还有does not work

最佳答案

通常,您无法撤消 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 ) 属性。


要覆盖,请使用简单的赋值。在这种情况下,您需要 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!
});

注意 writable 在使用 defineProperty 时默认为 false,而在使用简单语法时默认为 true o.attr = val; 定义一个(以前不存在的)属性。

关于javascript - 如何撤消 Object.defineProperty 调用?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7141210/

相关文章:

image - Chrome 84 中缩小的图像模糊

jQuery 触发器 ('click' )在 Chrome 中无法工作

javascript - 如何将外部 JSON 数据从上一个任务中生成的文件传递到任务?

node.js - 有没有类似于 async.waterfall 的东西,但有错误?

javascript - 尝试将数值转换为 css

Javascript Ajax 回调函数未定义错误

html - box-shadow 和 rgba(0, 0, 0, 0.5) 时的 Firefox 渲染问题

javascript - Sequelize options.nest in query() 方法不起作用

asp.net - 有没有办法检测更新面板何时完成刷新?

javascript - 使用 dojo 动态导入样式表