Как отменить объект.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);
какие варианты у меня есть в ES5, чтобы отменить defineProperty
звонок ?
нет глупых предложений типа Object.defineProperty = function() { }
пожалуйста.
следующее Object.defineProperty(Object.prototype, 'should', {})
тут не работает
и Object.defineProperty(Object.prototype, 'should', { value: undefined })
бросает!--25-->Uncaught TypeError: Cannot redefine property: defineProperty
в V8
Object.defineProperty(Object.prototype, 'should', {
set: function() {},
get: function() { return undefined; }
});
выдает ошибка
delete Object.prototype.should
и не работа
1 ответов
в общем, вы не можете отменить 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
для переключения между accessor (get
/set
) и данных (value
) свойства.
для перезаписи, используйте простые задания. В этом случае вам нужно writable
флаг true
. Очевидно, что это не работает со свойствами accessor. Он даже бросает исключение:
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
по умолчанию false
при использовании defineProperty
, а true
при использовании простого синтаксиса o.attr = val;
для определения (ранее не существовавшего) свойства.