简体   繁体   中英

How is the JS object mutable if the writable property defaults to false

I am trying to understand how the Object mutation in JS works. I came across the writable property on JS.

var x = {name:'JohnSnow'};

Object.defineProperty(x, 'name', {
   writable: false
};

Now changing the name property has no effect on the object x . This is understandable as I have changed its writable property to false .

However, all the docs that I read including ( https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/defineProperties#Parameters ) says that this property is false by default.

If the writable is set to false by default, shouldn't the object be immutable by default and should become mutable only after setting writable to true .

Am I wrong in understanding the concept of Object properties here, because I think all the objects in JS have this config and every object has writable property.

Object.defineProperty should usually only be used when defining a new property - otherwise, the property descriptor object passed will often be partially ignored, as described in step 2 of 9.1.6.3 ValidateAndApplyPropertyDescriptor .

In step 2, the new descriptor, desc , will only be put as the new property descriptor if the current descriptor is undefined.

In step 6, an existing data property might be switched to become an accessor property (or the other way around), but

Preserve the existing values of the converted property's [[Configurable]] and [[Enumerable]] attributes and set the rest of the property's attributes to their default values .

Steps 7 and 8 do not change the current descriptor, they simply verify and return a value.

So, no matter the descriptor passed, if the property already exists on the object, the writable property (or its absence) of the "new" descriptor will be completely ignored.


writable does default to false , but only when using Object.defineProperty .

 var x = {}; Object.defineProperty(x, 'name', { value: 'foo' }); x.name = 'bar'; console.log(x.name); 

As you can see above, if you do not provide a writable property when calling Object.defineProperty , it will default to false . That's all it means - it's not specifying that properties are always non-writable by default, it's only specifying that properties are non-writable when defining a property with Object.defineProperty .

Object properties are writable when defining an object with an object literal, described in 12.2.6.7 Runtime Semantics: Evaluation ObjectLiteral : {} :

  1. Perform ? PropertyDefinitionEvaluation of PropertyDefinitionList with arguments obj and true.

Which eventually leads you to:

CreateDataProperty ( O, P, V ) :

Let newDesc be the PropertyDescriptor { [[Value]]: V, [[Writable]]: true , [[Enumerable]]: true, [[Configurable]]: true }.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM