在 JavaScript 中,对象属性除了值之外,还有三个特殊的特性(称为"标志"或"属性描述符"):
每个对象属性都有以下标志:
true
,则可以修改值,否则它是只读的true
,则会在 for...in
循环中列出,否则不会true
,则属性可以被删除,这些标志也可以被修改,否则不能使用 Object.getOwnPropertyDescriptor
方法可以获取属性的完整信息:
let user = {
name: "John"
};
let descriptor = Object.getOwnPropertyDescriptor(user, 'name');
console.log(descriptor);
/* 输出:
{
value: "John",
writable: true,
enumerable: true,
configurable: true
}
*/
使用 Object.defineProperty
可以更改这些标志:
let user = {};
Object.defineProperty(user, "name", {
value: "John",
writable: false,
enumerable: true,
configurable: true
});
user.name = "Pete"; // 在严格模式下会报错,因为 writable 为 false
console.log(user.name); // "John"
使用 Object.defineProperties
可以一次定义多个属性:
let user = {};
Object.defineProperties(user, {
name: { value: "John", writable: false },
age: { value: 30, writable: true }
});
使用 Object.getOwnPropertyDescriptors
获取对象所有属性的描述符:
let descriptors = Object.getOwnPropertyDescriptors(user);
还有一些相关的方法可以限制整个对象:
Object.preventExtensions(obj)
- 禁止向对象添加新属性Object.seal(obj)
- 禁止添加/删除属性,设置所有现有属性为 configurable: false
Object.freeze(obj)
- 禁止添加/删除/更改属性,设置所有现有属性为 configurable: false, writable: false
Object.isExtensible(obj)
- 检查是否可添加属性Object.isSealed(obj)
- 检查是否已密封Object.isFrozen(obj)
- 检查是否已冻结这些属性标志和描述符提供了对对象属性的精细控制,是实现高级功能如不可变对象、私有属性模拟等的基础。