object.defineproperty用于精确控制对象属性行为,支持数据/访问器描述符,可设可读、可写、可枚举、可配置及getter/setter,是vue2响应式底层基础,但无法监听新增属性或数组索引赋值。

Object.defineProperty 用于精确控制对象属性的行为,比如是否可读、可写、可枚举、可配置,还能定义 getter/setter。它比直接赋值更底层,是实现响应式、冻结对象、隐藏属性等机制的基础。
基本语法和必需参数
调用格式为 Object.defineProperty(obj, prop, descriptor),其中:
- obj:要定义属性的目标对象
- prop:属性名(字符串或 Symbol)
- descriptor:描述符对象,包含控制属性行为的键值对
注意:如果目标对象不可扩展,不能添加新属性;若属性已存在且 configurable: false,后续只能修改 writable(且仅限从 true 改为 false),其他字段无法变更。
数据描述符 vs 访问器描述符
描述符分两类,**互斥使用**:不能同时设置 value 和 get,也不能同时设 writable 和 set。
-
数据描述符:含
value和writable(默认 false),如{ value: 42, writable: false } -
访问器描述符:含
get和/或set(函数),如{ get() { return this._x; }, set(v) { this._x = v; } }
两者都可配 enumerable(是否出现在 for...in / Object.keys)和 configurable(是否可删除或改描述符)。
常见实用场景
多数时候不是用来“定义新属性”,而是精细控制已有属性行为:
-
只读属性:设
writable: false,即使属性存在也阻止修改(严格模式下报错,非严格静默失败) -
隐藏属性:设
enumerable: false,使Object.keys()、for...in跳过该属性 -
拦截读写:用
get/set实现计算属性、日志、校验或响应式依赖收集 -
禁止删除或重定义:设
configurable: false,之后 delete 失败,再次 defineProperty 会报错(除非改 writable)
注意事项和陷阱
容易忽略但影响实际效果的关键点:
- 描述符对象中未显式声明的字段,值为 undefined,不是默认值。例如只写
{ value: 1 },writable是 undefined → 视为 false(不可写) - 在普通对象上多次对同一属性调用 defineProperty,若
configurable: false,后续只能降级writable,其余字段锁定 - Vue 2 的响应式核心依赖它,但它无法监听新增属性或数组索引赋值,所以 Vue 提供
Vue.set或vm.$set补充 - 建议始终显式写出所有需要的字段,避免隐式 false 带来的意外行为
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











