对象属性描述符是JavaScript控制属性行为的底层机制,分为数据属性(含value、writable、enumerable、configurable)和访问器属性(含get、set、enumerable、configurable),二者互斥且configurable为不可逆封印开关。

对象属性描述符是 JavaScript 控制属性行为的底层机制,它不暴露给开发者直接操作,但通过 Object.defineProperty() 和 Object.getOwnPropertyDescriptor() 可以读写其元信息。核心在于区分两种互斥类型:数据属性和访问器属性——它们各自拥有不同的控制维度,共同构成属性的“权限系统”。
数据属性描述符:值 + 三把锁
数据属性对应普通键值对(如 obj.x = 1),它的描述符由四个字段组成,其中三个是布尔型“开关”:
-
value:实际存储的数据,默认为
undefined -
writable:控制是否允许赋值修改。设为
false后,再执行obj.x = 2不会生效(非严格模式静默失败,严格模式报错) -
enumerable:决定该属性是否出现在
for...in、Object.keys()等枚举操作中 -
configurable:最严格的开关——若为
false,则无法删除该属性,也无法用defineProperty修改其他任何描述符(writable从true改为false是唯一例外)
注意:使用字面量创建的属性默认三者均为 true;而用 defineProperty 新增的属性,所有描述符默认为 false,更利于封装与防护。
访问器属性描述符:get/set + 两把锁
访问器属性不存值,而是靠函数拦截读写行为(如计算属性、副作用触发),它的描述符结构不同:
- get:读取属性时自动调用,返回值即为属性值;可返回派生结果或触发逻辑
- set:赋值时自动调用,接收新值作为参数;可用于校验、同步、通知等
-
enumerable 和 configurable:作用与数据属性一致,但默认值为
false
关键限制:get 和 set 必须与 value、writable 互斥。同时指定 value 和 get 会抛出 TypeError。只提供 get 是只读属性;只提供 set 是只写属性(读取时返回 undefined)。
configurable 是不可逆的“封印”
这个特性是两类描述符共有的最关键约束:
- 一旦设为
false,该属性就永久锁定:不能删、不能改描述符、不能切换类型(数据 ↔ 访问器) - 即使
configurable: false且writable: true,仍可通过defineProperty把它转成访问器属性——这是少数被允许的变更,常用于冻结原始值但保留行为扩展能力 - 判断一个属性是否已被“封印”,可检查
Object.getOwnPropertyDescriptor(obj, key).configurable
查看与定义:两个核心方法
所有控制都围绕这两个 API 展开:
-
Object.getOwnPropertyDescriptor(obj, key):获取单个自身属性的完整描述符对象,用于调试或条件判断 -
Object.defineProperty(obj, key, descriptor):定义或精细修改一个属性。descriptor 必须是纯数据描述符(含value)或纯访问器描述符(含get或set),不可混用
批量操作可用 Object.defineProperties();获取全部自身属性描述符可用 Object.getOwnPropertyDescriptors()。


















