属性描述符

js/property_descriptor2026-10-29 11:03:47

在 JavaScript 中,属性描述符(Property Descriptor)是一个对象,用于描述对象属性的特性。属性描述符可以分为两类:数据描述符(Data Descriptor)和访问器描述符(Accessor Descriptor)。它们分别用于描述数据属性和存取属性。

通过赋值添加的普通属性会在枚举属性时(例如 for...in、Object.keys() 等)出现,它们的值可以被更改,也可以被删除。Object.defineProperty() 允许精确地添加或修改对象上的属性,允许更改属性的额外细节,以使其不同于默认值。

属性描述符的类型

对象中存在的属性描述符有两种主要类型:数据描述符和访问器描述符。

  • 数据描述符 是一个具有可写或不可写值的属性。
  • 访问器描述符 是由 getter/setter 函数对描述的属性。

描述符只能是这两种类型之一,不能同时为两者。

数据描述符(Data Descriptor)

数据描述符用于描述具有值的属性。它包含以下属性:

  • value: 属性的值,默认为 undefined。
  • writable: 一个布尔值,表示属性的值是否可以被修改,默认为 false。
  • enumerable: 一个布尔值,表示属性是否可以被枚举(通过 for...in 或 Object.keys),默认为 false。
  • configurable: 一个布尔值,表示属性描述符是否可以被修改,以及属性是否可以被删除,默认为 false。

存取描述符(Accessor Descriptor)

存取描述符用于描述具有 getter 和 setter 的属性。它包含以下属性:

  • get: 一个函数,作为属性的 getter,如果没有 getter 则为 undefined。
  • set: 一个函数,作为属性的 setter,如果没有 setter 则为 undefined。
  • enumerable: 一个布尔值,表示属性是否可以被枚举,默认为 false。
  • configurable: 一个布尔值,表示属性描述符是否可以被修改,以及属性是否可以被删除,默认为 false。

获取属性描述符

获取单个属性

你可以使用 Object.getOwnPropertyDescriptor 方法来获取对象属性的描述符:

const obj = { prop: 42 };

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

获取多个属性

Object.getOwnPropertyDescriptors() 静态方法返回给定对象的所有自有属性描述符。

const object1 = {
  property1: 42,
};

const descriptors1 = Object.getOwnPropertyDescriptors(object1);

console.log(descriptors1.property1.writable);
// Expected output: true

console.log(descriptors1.property1.value);
// Expected output: 42

设置属性描述符

定义单个属性

Object.defineProperty() 静态方法会直接在一个对象上定义一个新属性,或修改其现有属性,并返回此对象。

默认情况下,使用 Object.defineProperty() 添加的属性是不可写、不可枚举和不可配置的。

此外,Object.defineProperty() 使用 [[DefineOwnProperty]] 内部方法,而不是 [[Set]],因此即使属性已经存在,它也不会调用 setter。

例如,定义数据描述符:

const obj = {};

Object.defineProperty(obj, 'dataProp', {
  value: 42,
  writable: true,
  enumerable: true,
  configurable: true
});

console.log(obj.dataProp); // 输出: 42

例如,定义存取描述符:

const obj = {};
let internalValue = 0;

Object.defineProperty(obj, 'accessorProp', {
  get() {
    return internalValue;
  },
  set(newValue) {
    internalValue = newValue;
  },
  enumerable: true,
  configurable: true
});

obj.accessorProp = 100;
console.log(obj.accessorProp); // 输出: 100

定义多个属性

Object.defineProperties() 静态方法直接在一个对象上定义新的属性或修改现有属性,并返回该对象。

const object1 = {};

Object.defineProperties(object1, {
  property1: {
    value: 42,
    writable: true,
  },
  property2: {},
});

console.log(object1.property1);
// Expected output: 42

参考

Object.getOwnPropertyDescriptor()
https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Object/getOwnPropertyDescriptor

Object.getOwnPropertyDescriptors()
https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Object/getOwnPropertyDescriptors

Object.defineProperties()
https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Object/defineProperties

Object.defineProperty()
https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Object/defineProperty

本页目录