NotCloseToFour NotCloseToFour - 6 months ago 12
Javascript Question

Setting Javascript property attributes directly instead of Object.defineProperty

I know that the proper way to set Javascript property attributes is to use the Object.defineProperty function, but I am curious what is preventing the setting of these values directly on the descriptor object that is returned via Object.getOwnPropertyDescriptor.

var a = new Object()
a.x = 1
var attributes = Object.getOwnPropertyDescriptor(a, 'x') //Object {value: 1, writable: true, enumerable: true, configurable: true}
var attributesOfWritable = Object.getOwnPropertyDescriptor(attributes, 'writable') //Object {value: true, writable: true, enumerable: true, configurable: true}
Object.getOwnPropertyDescriptor(a, 'x').writable = false
console.log(Object.getOwnPropertyDescriptor(a, 'x')) //Object {value: 1, writable: true, enumerable: true, configurable: true}
Object.defineProperty(a, 'x', {writable: false})
console.log(Object.getOwnPropertyDescriptor(a, 'x')) //Object {value: 1, writable: false, enumerable: true, configurable: true}


As shown in the code above, when looking at the descriptor object returned for the 'writable' property on the original descriptor object for a.x, the property is writable and configurable, which means setting the
writable
property of the property descriptor didn't change the underlying
x
property.

So I am unsure why I cannot just write:

Object.getOwnPropertyDescriptor(a, 'x').writable = false

Answer

That's because each time you use Object.getOwnPropertyDescriptor, FromPropertyDescriptor builds a new different object.

That object has no special setters, so altering its data won't affect the properties of the original object.

Instead, you should redefine the property:

var desc = Object.getOwnPropertyDescriptor(a, 'x');
desc.writable = false;
Object.defineProperty(a, 'x', desc);