Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I undo a Object.defineProperty call?

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

What options do I have in ES5 to undo a defineProperty call ?

No silly suggestions like Object.defineProperty = function() { } please.

The following Object.defineProperty(Object.prototype, 'should', {})

does not work

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

Throws a Uncaught TypeError: Cannot redefine property: defineProperty in V8

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

Throws the same error

delete Object.prototype.should also does not work

like image 582
Raynos Avatar asked Aug 21 '11 21:08

Raynos


People also ask

What is object defineProperty ()?

defineProperty() The static method Object. defineProperty() defines a new property directly on an object, or modifies an existing property on an object, and returns the object.

What is the difference between GET and defineProperty?

Using getter syntax you create a property which, prior to ES2015, you had to know the name of at the time that you were writing the code. Object. defineProperty allows you to perform the same as the above but, even before ES2015, does not require you to know the name of the property in advanced.

What parameters does the function object defineProperty () accept?

Object. defineProperty allows you to set whether or not the property is enumerable, writable, and configurable as well as a value or a get/set (getter/setter) pair (see MDN Object.

What is property descriptor?

A property descriptor is a record with some of the following attributes: value. The value associated with the property (data descriptors only). writable. true if and only if the value associated with the property may be changed (data descriptors only).


1 Answers

In general, you can't undo a defineProperty call, since there's no undo stack or something. The JS engine does not keep track of previous attribute descriptors.

For example,

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

What you can do is remove or reconfigure an attribute, or overwrite its value. As mentioned in the other answer, the configurable flag is required to be true if you want to remove or reconfigure. Once a property is defined with configurable:false, you cannot change the configurable flag.


To remove an attribute (this is supposedly what you want to do), use 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 

To reconfigure, use defineProperty again and pass a different descriptor:

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 

As shown in this sample, you can use defineProperty to switch between accessor (get/set) and data (value) properties.


To overwrite, use simple assignment. In this case, you need the writable flag to be true. Obviously this does not work with accessor properties. It even throws an exception:

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

Note that writable defaults to false when you use defineProperty, but true when you use the simple syntax o.attr = val; to define a (previously not existing) property.

like image 129
user123444555621 Avatar answered Sep 21 '22 12:09

user123444555621