The ECMAScript language specification defines the [[writable]] attribute of Object.defineProperty() as following:
- If false, attempts by ECMAScript code to change the property’s [[Value]] attribute using [[Set]] will not succeed.
However, this definition doesn’t make any sense. There it says that if [[writable]] is false, any attempts to use [[set]] will not work. So in other words: if [[writable]] is false then we can’t change it to an accessor property of a setter.
However, in the example below we have an object where we are able to define [[set]] despite [[writable]] being false:
var plainObj = new Object(); Object.defineProperty(plainObj, "v1", { configurable: true, writable: false, //<---- attribute [[writable]] is 'false' value: "handsome-and-SKINNY" }); //setting an [[set]] attribute: Object.defineProperty(plainObj, "v1", { set: function (input) { console.log("Setter's value: " + input); } }); //passing argument to setter plainObj.v1 = "passed argument";
Console output:
Setter's value: passing argument
So as you can see, we have successfully defined an [[set]] attribute and passed in some arguments into it, despite the fact that it shoudn’t be happening because [[writable]] was set to false. Any explenations are appreciated.
Advertisement
Answer
If false, attempts by ECMAScript code to change the property’s [[Value]] attribute using [[Set]] will not succeed.
However, this definition doesn’t make any sense. There it says that if [[writable]] is false, any attempts to use [[set]] will not work.
You misunderstood the specification.
When the property is a data property, it is defined by the [[Value]] and [[Writable]] attributes, [[Get]] and [[Set]] are not present. When the property is an accessor property, it is defined by the [[Get]] and [[Set]] attributes, [[Value]] and [[Writable]] are not present.
The phrase “change the property’s [[Value]] attribute using [[Set]] will not succeed.” does not refer to the [[Set]] attribute of a data property descriptor record, it refers to the [[Set]]() internal object method which will not succeed.
Your example code did change the data property into an accessor property, thereby also removing the [[Writable]] attribute. It now can be written to as long as there is a setter.