属性描述符 - DeepSeek

在 JavaScript 中,属性描述符(Property Descriptor)是用于描述对象属性特性的对象。每个对象的属性都有一个对应的属性描述符,它定义了该属性的行为。属性描述符分为两种类型:数据描述符存取描述符

1. 数据描述符(Data Descriptor)

数据描述符用于描述一个具有值的属性,包含以下可选键:

  • value: 属性的值,默认为 undefined

  • writable: 布尔值,表示属性值是否可以被修改,默认为 false

  • enumerable: 布尔值,表示属性是否可以在 for...in 循环或 Object.keys() 中被枚举,默认为 false

  • configurable: 布尔值,表示属性是否可以被删除或修改其特性(如将 writablefalse 改为 true),默认为 false

示例:

const obj = {};

Object.defineProperty(obj, 'name', {
  value: 'Alice',
  writable: false,       // 不可修改
  enumerable: true,       // 可枚举
  configurable: false    // 不可删除或修改特性
});

console.log(obj.name); // Alice
obj.name = 'Bob';      // 静默失败(严格模式下会报错)
console.log(obj.name); // Alice

for (let key in obj) {
  console.log(key);    // name
}

2. 存取描述符(Accessor Descriptor)

存取描述符用于描述一个通过 getter 和 setter 访问的属性,包含以下可选键:

  • get: 函数,当访问属性时调用,默认为 undefined

  • set: 函数,当设置属性时调用,默认为 undefined

  • enumerable: 布尔值,表示属性是否可枚举,默认为 false

  • configurable: 布尔值,表示属性是否可配置,默认为 false

示例:

const obj = {
  _age: 25
};

Object.defineProperty(obj, 'age', {
  get() {
    return this._age;
  },
  set(value) {
    if (value > 0) {
      this._age = value;
    }
  },
  enumerable: true,
  configurable: true
});

console.log(obj.age); // 25
obj.age = 30;
console.log(obj.age); // 30
obj.age = -10;        // 设置无效
console.log(obj.age); // 30

3. 获取属性描述符

可以使用 Object.getOwnPropertyDescriptor 方法获取某个属性的描述符。

示例:

const obj = { name: 'Alice' };
const descriptor = Object.getOwnPropertyDescriptor(obj, 'name');

console.log(descriptor);
// 输出:
// {
//   value: 'Alice',
//   writable: true,
//   enumerable: true,
//   configurable: true
// }

4. 修改属性描述符

使用 Object.definePropertyObject.defineProperties 可以修改或定义属性的描述符。

示例:

const obj = { name: 'Alice' };

Object.defineProperty(obj, 'name', {
  writable: false
});

obj.name = 'Bob'; // 静默失败(严格模式下会报错)
console.log(obj.name); // Alice

5. 默认行为

当通过普通方式(如字面量或赋值)创建属性时,属性描述符的默认值为:

  • value: 属性的值。

  • writable: true

  • enumerable: true

  • configurable: true

示例:

const obj = { name: 'Alice' };
console.log(Object.getOwnPropertyDescriptor(obj, 'name'));
// 输出:
// {
//   value: 'Alice',
//   writable: true,
//   enumerable: true,
//   configurable: true
// }

6. 注意事项

  • 如果同时使用数据描述符和存取描述符(如同时设置 valueget),会抛出错误。

  • 修改不可配置的属性(configurable: false)会抛出错误。

  • 在严格模式下,违反 writable: falseconfigurable: false 的规则会抛出错误。


通过属性描述符,JavaScript 提供了对对象属性行为的细粒度控制,这在实现高级功能(如数据绑定、属性校验等)时非常有用。

Last updated