una que propiedad property polyfill objeto mdn existing delete agregar javascript google-chrome node.js defineproperty

javascript - que - object defineproperty polyfill



¿Cómo deshago una llamada Object.defineProperty? (1)

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

¿Qué opciones tengo en ES5 para deshacer una llamada defineProperty ?

No hay sugerencias tontas como Object.defineProperty = function() { } por favor.

El siguiente Object.defineProperty(Object.prototype, ''should'', {})

no funciona

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

Emite un Uncaught TypeError: Cannot redefine property: defineProperty en V8

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

Lanza el mismo error

delete Object.prototype.should tampoco funciona


En general, no puede deshacer una llamada defineProperty , ya que no hay una pila de deshacer o algo así. El motor JS no realiza un seguimiento de los descriptores de atributos anteriores.

Por ejemplo,

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

Lo que puede hacer es eliminar o reconfigurar un atributo, o sobrescribir su valor. Como se mencionó en la otra respuesta, se requiere que el indicador configurable sea true si desea eliminar o reconfigurar. Una vez que una propiedad se define con configurable:false , no puede cambiar el indicador configurable .

Para eliminar un atributo (esto es supuestamente lo que quieres hacer), usa 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

Para reconfigurar, use defineProperty nuevamente y pase un descriptor diferente:

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

Como se muestra en este ejemplo, puede usar defineProperty para cambiar entre las defineProperty de acceso ( get / set ) y datos ( value ).

Para sobrescribir, usa la tarea simple. En este caso, necesita que la writable sea true . Obviamente, esto no funciona con las propiedades de acceso. Incluso arroja una excepción:

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

Tenga en cuenta que el valor predeterminado de writable es false cuando usa defineProperty , pero true cuando usa la sintaxis simple o.attr = val; Para definir una propiedad (previamente no existente).