如何利用 Object.defineProperties 一次性为对象配置多个具有特定权限的属性

作者:袖梨 2026-06-07
Object.defineProperties 是 JavaScript 中批量定义或修改对象属性特性的方法,支持数据描述符(value/writable)和存取描述符(get/set),需注意描述符互斥、configurable 限制及与 freeze/seal 配合使用。

Object.defineProperties 是 JavaScript 中批量定义或修改对象属性的高效方式,它允许你为多个属性分别指定 valuewritableenumerableconfigurable 等特性,从而精细控制每个属性的访问权限和行为。

明确每个属性的描述符结构

每个属性需以键名作为对象的属性名,值为一个属性描述符(descriptor)对象。描述符分为两类:

  • 数据描述符:含 valuewritableenumerableconfigurable
  • 存取描述符:含 getsetenumerableconfigurable(不能与数据描述符混用)

例如,定义一个只读、不可枚举、不可配置的私有字段:

const obj = {};
Object.defineProperties(obj, {
  id: { value: 123, writable: false, enumerable: false, configurable: false },
  name: { value: 'Alice', writable: true, enumerable: true, configurable: false }
});

组合使用可写/只读 + 可枚举/不可枚举

常见权限组合示例如下:

  • 常量属性writable: false, configurable: false, enumerable: true(如 PI
  • 内部状态(不暴露给 for...in 或 JSON.stringify)enumerable: false,同时设 configurable: false 防止被删除
  • 仅可读、可配置的属性:用 get 定义,set: undefined 或省略,configurable: true 允许后续重定义

注意:configurable: false 后不能再将属性改为 configurable: true,也不能从数据描述符转为存取描述符(反之亦然)。

避免常见陷阱

  • 遗漏 valueget/set:会导致属性值为 undefined,且无法通过赋值触发预期逻辑
  • 同时设置 valueget:会抛出 TypeError
  • 对已存在属性重复定义时,configurable: false 的属性无法修改其 writable 状态以外的其他特性(比如不能把 enumerable: false 改成 true
  • 在严格模式下对 writable: false 属性赋值会静默失败(非严格模式下也无效,但不报错)

配合 Object.freeze 或 Object.seal 进行强化保护

Object.defineProperties 本身不冻结对象,只是逐个设置属性特性。若需彻底锁定对象,可后续调用:

  • Object.freeze(obj):使所有现有属性 configurable: falsewritable: false,并禁止添加新属性
  • Object.seal(obj):仅禁用新增/删除属性,保留已有属性的 writable 权限

建议顺序:先用 defineProperties 精细配置,再按需 freezeseal,避免覆盖已有设定。

相关文章

精彩推荐