[Front-end knowledge] JavaScript - attributes and attributes
1. Data attributes
A data attribute contains a location to hold a data value. Values are read from and written to this location.
Four characteristics of data attributes:
characteristic | describe |
---|---|
[[Configurable]] | Indicates whether the property can be deleted and redefined via delete, whether its properties can be modified, and whether it can be changed to an accessor property. |
[[Enumerable]] | Indicates whether the attribute can be returned by a for-in loop. |
[[Writable]] | Indicates whether the property's value can be modified. |
[[Value]] | Contains the actual value of the attribute |
// 当我们创建一个对象时,name的值会被设置到 [[Value]]特性中,[[Configurable]]、[[Enumerable]]和[[Writable]] 都会被设置为 true
let person = {
name: "Outman"
};
If you want to modify the default value of a property, you can use the Object.defineProperty() method:
- Modify writable attributes
let person = {
};
Object.defineProperty(person, "name", {
writable: false, // 表示不可修改
value: "Outman"
});
console.log(person.name); // "Outman"
person.name = "manOut"; // 尝试修改name属性
console.log(person.name); // "Outman",无法修改name值,因为 writable 为 false
- Modify configurable attributes
let person = {
};
Object.defineProperty(person, "name", {
configurable: false, // 表示不可配置
value: "Outman"
});
console.log(person.name); // "Outman"
delete person.name; // 尝试 delete name属性
console.log(person.name); // "Outman",无法delete name属性,因为 configurable 为 false
// 另外,值得一提的是,一个属性被定义为不可配置之后,将无法再变回可配置的!
2. Accessor properties
Contains a getter function and a setter function, but these two functions are not required.
characteristic | describe |
---|---|
[[Configurable]] | Indicates whether the attribute can be deleted and redefined by delete, whether its properties can be modified, and whether it can be changed to a data attribute. |
[[Enumerable]] | Indicates whether the attribute can be returned by a for-in loop. |
[[Get]] | Getter function, called when the property is read. |
[[Set]] | Setter function, called when the property is written. |
The properties of accessor properties are also modified via Object.defineProperty():
// 定义一个对象,包含伪私有成员 year_和公共成员 edition
let book = {
year_: 2017,
edition: 1
};
Object.defineProperty(book, "year", {
get() {
return this.year_;
},
set(newValue) {
if (newValue > 2017) {
this.year_ = newValue;
this.edition += newValue - 2017;
}
}
});
book.year = 2018;
console.log(book.edition); // 2
3. Define multiple attributes
To define multiple properties, you can use the Object.defineProperties() method:
let book = {
};
Object.defineProperties(book, {
year_: {
value: 2017
},
edition: {
value: 1
},
year: {
get() {
return this.year_;
},
set(newValue) {
if (newValue > 2017) {
this.year_ = newValue;
this.edition += newValue - 2017;
}
}
}
});
Fourth, the characteristics of reading attributes
To read the properties of a property, you can use the Object.getOwnPropertyDescriptor() method; to read multiple properties of a property, you can use the Object.getOwnPropertyDescriptors() static method newly added in ECMAScript 2017. This method calls Object.getOwnPropertyDescriptor() on each owned property and returns them in a new object.
let descriptor = Object.getOwnPropertyDescriptor(book, "year_");
console.log(descriptor.value); // 2017
console.log(descriptor.configurable); // false
console.log(typeof descriptor.get); // "undefined"
let descriptor = Object.getOwnPropertyDescriptor(book, "year");
console.log(descriptor.value); // undefined
console.log(descriptor.enumerable); // false
console.log(typeof descriptor.get); // "function"
console.log(Object.getOwnPropertyDescriptors(book));
// {
// edition: {
// configurable: false,
// enumerable: false,
// value: 1,
// writable: false
// },
// year: {
// configurable: false,
// enumerable: false,
// get: f(),
// set: f(newValue),
// },
// year_: {
// configurable: false,
// enumerable: false,
// value: 2017,
// writable: false
// }
// }