Provide a way to draw a distinction between the characteristics of properties, such as whether the property was read-only or not.
var myObject = {
a: 2
};
Object.getOwnPropertyDescriptor(myObject, 'a'); // => {value: 2, writable: true, enumerable: true, configurable: true}-
The property descriptor includes three characteristics other than the value of a property:
writable,enumerableandconfigurable. -
We can use
Object.defineProperty()to add a new property, or modify an existing one (if it's configurable). E.g
var myObject = {};
Object.defineProperty(myObject, 'a', {
value: 2,
writable: true,
configurable: true,
enumerable: true
});
myObject.a; // => 2The ability to change the value of a property is controlled by writable. E.g
var myObject = {};
Object.defineProperty(myObject, 'a', {
value: 2,
writable: false, // not writable
configurable: true,
enumerable: true
});
myObject.a = 3;
myObject.a; // => 2- In strict mode the parser will return an error if we try to modify the property
var myObject = {};
Object.defineProperty(myObject, 'a', {
value: 2,
writable: false, // not writable
configurable: true,
enumerable: true
});
myObject.a = 3; // => TypeError: 'a' is read-onlyAs long as a property is currently configurable we can modify its descriptor definition using the same defineProperty() utility. E.g
var myObject = {
a: 2
};
myObject.a = 3;
myObject.a; // => 3
Object.defineProperty(myObject, 'a', {
value: 4,
writable: true,
configurable: false, // not configurable
enumerable: true
});
myObject.a; // => 4
myObject.a = 5;
myObject.a // => 5
Object.defineProperty(myObject, 'a', {
value: 6,
writable: true,
configurable: true,
enumerable: true
}); // => TypeError: can't redefine non-configurable property "a"-
Changing
configurabletofalseis a one-way action and can't be undone -
configurable: falsealso prevents the ability to use thedeleteoperator to remove an existing property. E.g
var myObject = {
a: 2
};
myObject.a; // => 2
delete myObject.a;
myObject.a // => undefined
Object.defineProperty(myObject, 'a', {
value: 2,
writable: true,
configurable: false,
enumerable: true
});
myObject.a; // => 2
delete myObject.a;
myObject.a // => 2Controls if a property will show up in certain object-property enumerations, such as for...in loop. E.g
var myObject = {
a: 1,
b: 2,
c: 3
};
Object.defineProperty(myObject, 'b', {
value: 2,
writable: true,
configurable: true,
enumerable: false
});
for (prop in myObject) {
console.log(myObject[prop]);
} // => 1, 3- Object constant: By combining
writable: falseandconfigurable: false, you can create a constant as an object property. E.g
var myObject = {};
Object.defineProperty(myObject, 'FAV_NUMBER', {
value: 42,
writable: false,
configurable: false
});'use strict';
var myObject = {
a: 2
};
Object.preventExtensions(myObject);
myObject.b = 3; // TypeError: can't define property "b": Object is not extensibleCreates a "sealed" object, which means it takes an existing object and essentially calls Object.preventExtensions() on it, but it also marks all existing properties as configurable: false. E.g
'use strict'
var myObject = {
a: 1,
b: 2,
c: 3
};
Object.seal(myObject);
myObject.d = 4; // => TypeError: can't define property "d": Object is not extensible
Object.defineProperty(myObject, 'b', {
enumerable: false
}); // => TypeError: can't redefine non-configurable property "b"- So not only can we not add any more properties, but we also can't reconfigure or delete any existing properties (though you can still modify their values)
Creates a frozen object, which means it takes an existing object and essentially calls Object.seal()on it, and it also marks all "data accessor" properties as writable: false so their values can't be changed. E.g
'use strict'
var myObject = {
a: 1,
b: 2,
c: 3
};
Object.freeze(myObject);
myObject.a = 4; // => TypeError: "a" is read-only-
This approach is the highest level of immutability that you can attain for an object as it prevents any changes to the object or any of its direct properties
-
Though the contents of any referenced other objects are unaffected.