Chapter 7: Object properties configuration
7.1 Property flags and descriptors
Property flags
writable
β iftrue
, the value can be changed, otherwise itβs read-only.enumerable
β iftrue
, then listed in loops, otherwise not listed.configurable
β iftrue
, the property can be deleted and these attributes can be modified, otherwise not.
Get the flags
let descriptor = Object.getOwnPropertyDescriptor(obj, propertyName);
let user = {
name: "John"
};
let descriptor = Object.getOwnPropertyDescriptor(user, 'name');
/* property descriptor:
{
"value": "John",
"writable": true,
"enumerable": true,
"configurable": true
}
*/
Change the flags
Object.defineProperty(obj, propertyName, descriptor);
If the property exists, defineProperty
updates its flags. Otherwise, it creates the property with the given value and flags. If a flag is not supplied, it is assumed false.
Making a property non-configurable is a one-way road. We cannot change it back with defineProperty
.
Multiple properties
Define many properties at once:
Object.defineProperties(obj, {
prop1: descriptor1,
prop2: descriptor2
// ...
});
Get all property descriptors at once:
Object.getOwnPropertyDescriptors(obj));
If we want a better clone, Object.defineProperties
is preferred.
7.2 Property getters and setters
Getters and setters
let obj = {
get propName() {
// getter, the code executed on getting obj.propName
},
set propName(value) {
// setter, the code executed on setting obj.propName = value
}
};
For example:
let user = {
name: "John",
surname: "Smith",
get fullName() {
return `${this.name} ${this.surname}`;
}
set fullName(value) {
[this.name, this.surname] = value.split(" ");
}
};
user.fullName = "Alice Cooper";
alert(user.surname); // Cooper
Accessor descriptors
For accessor properties, there is no value
or writable
, but instead there are get
and set
functions.
To create an accessor fullName
with defineProperty
:
Object.defineProperty(user, 'fullName', {
get() {
return `${this.name} ${this.surname}`;
},
set(value) {
[this.name, this.surname] = value.split(" ");
}
});
Smarter getters/setters
Getters/setters can be used as wrappers over "real" property values to gain more control over operations with them.
set name(value) {
if (value.length < 4) {
alert("Name is too short, need at least 4 characters");
return;
}
this._name = value;
}
Last updated