Skip to content

属性描述符与存取器

在 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 提供了强大的能力来控制对象属性的行为。通过属性描述符,你可以精确地控制属性的可见性和可变性;而通过存取器,你可以在属性被访问或修改时插入自定义逻辑。这些特性在实现数据验证、依赖跟踪、计算属性等方面非常有用,同时也提高了代码的安全性和灵活性。

Released under the MIT License.