In generale, non è possibile annullare una chiamata defineProperty
, poiché non c'è stack di annullamento o qualcosa del genere. Il motore JS non tiene traccia dei descrittori degli attributi precedenti.
Per esempio,
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
});
Che cosa si può fare è rimuovere o riconfigurare un attributo, o sovrascrivere il suo valore. Come menzionato nell'altra risposta, il flag configurable
deve essere true
se si desidera rimuovere o riconfigurare. Una volta definita una proprietà con configurable:false
, non è possibile modificare il flag configurable
.
Per rimuovere un attributo (questo è presumibilmente ciò che si vuole fare), utilizzare 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
riconfigurare utilizzare defineProperty
di nuovo e passare un descrittore diversa:
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
Come mostrato in questo esempio, è possibile utilizzare defineProperty
per passare da acc proprietà (get
/set
) e dati (value
).
Per sovrascrivere, utilizzare la semplice assegnazione. In questo caso, è necessario che il flag writable
sia true
. Ovviamente questo non funziona con le proprietà accessorie. E lancia anche un'eccezione:
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!
});
Nota che writable
default false
quando si utilizza defineProperty
, ma true
quando si utilizza la sintassi semplice o.attr = val;
per definire una proprietà (prima non esistenti).
qualcuno può spiegare perché non possiamo sovrascrivere o rimuovere un 'accessorio' assegnando un nuovo valore alla proprietà come questo 'obj.foo =' nuovo valore '; '? in altre parole, perché dobbiamo eliminare prima la proprietà o riconfigurarla per sbarazzarci di tale accessor – kapreski