在 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