object.defineproperty 是 javascript 中用于精确控制对象单个属性行为的核心方法,支持数据描述符(含 value/writable)和存取描述符(含 get/set),二者不可混用;configurable、enumerable、writable 控制属性的可删除性、可枚举性和可写性,常用于创建只读属性、响应式系统或隐藏内部属性。

Object.defineProperty 是 JavaScript 中用于精确控制对象属性行为的核心方法,它允许你定义或修改对象的**单个属性**,并指定其可枚举性、可配置性、可写性,甚至自定义 getter/setter。它不适用于批量操作,也不直接改变已有属性的值——而是改变属性的“描述符”(descriptor)。
属性描述符类型:数据描述符 vs. 存取描述符
每个属性必须属于以下两类之一,**不能混用**:
-
数据描述符:包含
value和writable(也可含enumerable、configurable); -
存取描述符:包含
get和/或set(同样可含enumerable、configurable)。
如果 descriptor 中同时出现 value 或 writable 与 get 或 set,会抛出 TypeError。
四个关键布尔属性的含义与限制
configurable:决定该属性是否能被删除、是否能修改其描述符(除 value 和 writable 外,比如从数据描述符改为存取描述符需为 true)。一旦设为 false,就不可逆转。
enumerable:控制该属性是否出现在 for...in 循环和 Object.keys() 等枚举操作中。默认为 false(即不可枚举)。
writable:仅对数据描述符有效,决定 value 是否可被赋值运算符(=)更改。设为 false 后,再赋值在非严格模式下静默失败,严格模式下抛 TypeError。
value:数据描述符的初始值,默认为 undefined;get/set 函数则必须是函数或 undefined。
常见使用场景与注意事项
- 创建只读属性:
writable: false+configurable: false(常用于冻结关键字段); - 实现响应式逻辑(如 Vue 2 的数据劫持):用
get/set拦截访问与赋值; - 隐藏内部属性:设
enumerable: false,使其不出现在JSON.stringify或遍历中; - 不能直接用它添加到原型链上影响继承行为——它只作用于目标对象自身属性;
- 对数组索引属性使用时要小心:
Object.defineProperty(arr, '0', {...})可以,但不会触发数组长度更新或影响push等方法的内置行为。
与 Object.defineProperties 和 class 字段的区别
Object.defineProperties(obj, descriptors) 是批量版本,接受一个属性名→描述符的映射对象。
ES6+ 的 class 中的字段声明(prop = value)创建的是**可枚举、可写、可配置**的自有属性,等价于隐式调用 defineProperty 但参数固定;而手动用 defineProperty 可打破这些默认,实现更细粒度控制。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











