2.3 KiB
2.3 KiB
Object.defineProperty
方法
一、基本概念
Object.defineProperty()
是 JavaScript 中用于直接在一个对象上定义一个新属性,或者修改一个对象的现有属性的方法。它允许精确控制属性的行为特性。
属性描述符详解
1. 数据描述符(已注释部分)
{
value: 18, // 属性值
enumerable: true, // 是否可枚举(for...in或Object.keys())
writable: true, // 是否可修改
configurable: true // 是否可删除或修改特性
}
2. 存取描述符(实际使用部分)
{
get() {
// 读取属性时调用
return age;
},
set(value) {
// 设置属性时调用
age = value;
}
}
特性说明
特性 | 类型 | 默认值 | 描述 |
---|---|---|---|
configurable | 布尔 | false | 是否可删除属性或修改特性 |
enumerable | 布尔 | false | 是否出现在枚举属性中 |
value | 任意 | undefined | 属性值 |
writable | 布尔 | false | 是否可被赋值运算符改变 |
get | 函数 | undefined | 读取属性时调用的函数 |
set | 函数 | undefined | 设置属性时调用的函数 |
使用场景
- 实现数据响应式(如Vue2的核心实现)
- 创建私有属性(通过getter/setter控制访问)
- 属性访问拦截(在读取或设置时执行额外操作)
- 定义不可枚举属性(如内置对象的一些方法)
注意事项
- 数据描述符(value, writable)和存取描述符(get, set)不能同时使用
- 默认情况下,通过defineProperty添加的属性不可枚举、不可写、不可配置
- 在严格模式下,setter必须设置一个参数,否则会抛出错误
- getter不应有副作用(如修改其他属性值)
实现简单响应式
function defineReactive(obj, key, val) {
Object.defineProperty(obj, key, {
get() {
console.log(`读取 ${key}: ${val}`);
return val;
},
set(newVal) {
console.log(`设置 ${key}: ${newVal}`);
val = newVal;
}
});
}
const data = {};
defineReactive(data, 'message', 'Hello');