enumerable
most likely the only one we all expect: if false, a classic for/in loop will not expose the property, otherwise it will. enumerable is false by default.writable
just a bit more tricky than we think. Nowadays, if a property is defined as non writable, no error will occur the moment we'll try to change this property:
var o = {};
Object.defineProperty(o, "test", {
writable: false,
value: 123
});
o.test; // 123
o.test = 456; // no error at all
o.test; // 123
So the property is not writable but nothing happens unless we try to redefine that property.
Object.defineProperty(o, "test", {
writable: false,
value: 456
});
// throws
// Attempting to change value of a readonly property.
Got it ? Every time we would like to set a property of an unknown object, or one shared in an environment we don't trust, either we use a try/catch plus double check, or we must be sure that Object.getOwnPropertyDescriptor(o, "test").writable is true.
writable is false by default too.
configurable
This is the wicked one ... what would you expect from configurable ?- I cannot set a different type of value
- I cannot re-configure the descriptor
var o = Object.defineProperty({}, "test", {
enumerable: false,
writable: true,
configurable: false, // note, it's false
value: 123
});
Do you think this would be possible ?
Object.defineProperty(o, "test", {
enumerable: false,
writable: false, // note, this is false only now
configurable: false,
value: "456" // note, type and value is different
});
// did I re-configure it ?
o.test === "456"; // true !!!
Good, so a variable that is writable can be reconfigured on writable attribute and on its type.
The only attribute that cannot be changed, once flagged as configurable and bear in mind that false is the default, is configurable itself plus enumerable.
Also writable is false by default.
This inconsistency about configurable seems to be pretty much cross platform and probably meant ... why ?
Brainstorming
If I can't change the value the descriptor must be configurable at least on writable property ... no wait, if I can set the value as not writable then configurable should be set as false otherwise it will loose its own meaning ... no, wait ...How It Is
writable is the exception that confirms the rule. If true, writable can always be configurable while if false, writable becomes automatically not configurable and the same is true for both get and set properties ... these acts as writable: false no matters how configurble is set.How Is It If We Do Not Define
// simple object
var o = {};
// simple assignment
o.test = 123;
// equivalent in Object.defineProperty world
Object.defineProperty(o, "test", {
configurable: true,
writable: true,
enumerable: true,
value: 123
});
Thanks to @jdalton to point few hints out.
As Summary
The configurable property works as expected with configurable itself and only with enumerable one.If we think that writable has anything to do with both of them we are wrong ... at least now we know.
No comments:
Post a Comment