属性描述符与存取器
在 ES6(ECMAScript 2015)中,属性描述符(Property Descriptors)和存取器(Getters and Setters)为对象属性的定义提供了更精细的控制。通过这些机制,你可以自定义属性的行为,包括如何获取、设置属性值,以及属性是否可枚举、可配置或可写。
属性描述符
属性描述符是用于定义或修改对象属性特性的元数据。每个属性都有对应的属性描述符,它可以是“数据描述符”或者“存取描述符”,但不能同时是两者。
- 数据描述符:包含值、可写性、可枚举性和可配置性。
- 存取描述符:由一组获取函数和设置函数组成,并且可以是可枚举和可配置的。
使用 Object.defineProperty 定义属性
可以通过Object.defineProperty()方法来定义新属性或修改现有属性,并指定其描述符。
javascript
let obj = {};
Object.defineProperty(obj, "name", {
value: "Alice",
writable: true,
enumerable: true,
configurable: true,
});
console.log(obj.name); // 输出: Alice获取属性描述符
使用Object.getOwnPropertyDescriptor()可以查看已定义的属性描述符。
javascript
let descriptor = Object.getOwnPropertyDescriptor(obj, "name");
console.log(descriptor.value); // 输出: Alice
console.log(descriptor.writable); // 输出: true存取器(Getters and Setters)
存取器允许你定义属性的读取(get)和设置(set)操作。它们提供了一种拦截对对象属性访问的方法,使得可以在获取或设置属性值时执行额外的逻辑。
定义存取器
可以直接在对象字面量中定义 getter 和 setter:
javascript
let person = {
firstName: "Alice",
lastName: "Smith",
get fullName() {
return `${this.firstName} ${this.lastName}`;
},
set fullName(name) {
[this.firstName, this.lastName] = name.split(" ");
},
};
console.log(person.fullName); // 输出: Alice Smith
person.fullName = "Bob Johnson";
console.log(person.firstName); // 输出: Bob
console.log(person.lastName); // 输出: Johnson也可以使用Object.defineProperty()来添加存取器:
javascript
let person = {
firstName: "Alice",
lastName: "Smith",
};
Object.defineProperty(person, "fullName", {
get() {
return `${this.firstName} ${this.lastName}`;
},
set(name) {
[this.firstName, this.lastName] = name.split(" ");
},
});
console.log(person.fullName); // 输出: Alice Smith
person.fullName = "Charlie Brown";
console.log(person.firstName); // 输出: Charlie
console.log(person.lastName); // 输出: Brown总结
属性描述符和存取器为 JavaScript 提供了强大的能力来控制对象属性的行为。通过属性描述符,你可以精确地控制属性的可见性和可变性;而通过存取器,你可以在属性被访问或修改时插入自定义逻辑。这些特性在实现数据验证、依赖跟踪、计算属性等方面非常有用,同时也提高了代码的安全性和灵活性。