一、基本语法
Object.defineProperty(obj, prop, descriptor)
- obj:目标对象
- prop:要定义或修改的属性名
- descriptor:属性描述符(包含配置信息)
二、属性描述符类型
分为 数据描述符 和 存取描述符,二者不可混用。
1. 数据描述符
- value:属性值(默认
undefined
) - writable:是否可修改(默认
false
) - enumerable:是否可枚举(如出现在
for...in
循环中,默认false
) - configurable:是否可删除或重新配置(默认
false
)
示例:
const obj = {};
Object.defineProperty(obj, 'a', {
value: 42,
writable: false,
enumerable: true,
configurable: true
});
obj.a = 100; // 静默失败(严格模式报错)
console.log(obj.a); // 42
2. 存取描述符
- get:获取属性值的函数(默认
undefined
) - set:设置属性值的函数(默认
undefined
)
示例:
let internalValue = 0;
Object.defineProperty(obj, 'b', {
get() {
return internalValue;
},
set(newVal) {
internalValue = newVal;
console.log('值被修改为:', newVal);
},
enumerable: true
});
obj.b = 5; // 输出 "值被修改为:5",会调用set方法。另外要使用中间变量,不能使用obj.属性名这种
,会一直递归直至栈溢出```
### 三、关键特性说明
1. **默认值**:除`value`默认为`undefined`外,`writable`、`enumerable`、`configurable`默认均为`false`。
2. **configurable: false** 时:
- 不能修改除`writable`之外的描述符(`writable`只能从`true`改为`false`)
- 不能删除属性
3. **应用场景**:
- 实现数据响应式(如Vue2的响应式核心)
- 控制属性的访问和修改权限
- 隐藏内部实现细节(通过不可枚举性)
### 四、与直接赋值的区别
```javascript
obj.c = 10; // 等价于:
Object.defineProperty(obj, 'c', {
value: 10,
writable: true,
enumerable: true,
configurable: true
});
五、注意事项
- 性能:频繁调用会影响性能,尤其在大型对象上
- 兼容性:ES5+支持,IE9+基本支持
- 局限性:无法监听新增属性(需配合
Object.defineProperties()
或使用Proxy)
六、简单响应式示例
const data = {};
let domElement = document.getElementById('display');
let _value;
Object.defineProperty(data, 'message', {
get() {
return _value;
},
set(newVal) {
_value = newVal;
domElement.textContent = newVal; // 自动更新DOM
}
});
data.message = 'Hello World!'; // 页面显示更新