object defineproperty 和 Proxy的对比
好问题!简单直接地说:
Object.defineProperty 和 Proxy 都可以用来拦截或控制对象的读写操作,但他们的能力、使用场景、灵活性差别蛮大的。
下面我帮你一条条对比清楚:
| 特性 | Object.defineProperty |
Proxy |
|---|---|---|
| 作用对象 | 直接在对象的单个属性上定义 getter/setter | 可以拦截整个对象的所有操作 |
| 可拦截的操作 | 只限于属性的读取和赋值 | 几乎可以拦截所有操作(读、写、删、in、for...in 等) |
| 适用粒度 | 单个属性 | 整个对象 |
| 语法复杂度 | 需要一个个属性去定义 | 一次性定义统一的处理逻辑 |
| 动态新增属性拦截 | 不支持(新增的属性不会自动带 getter/setter) | 支持(拦截所有属性访问,包括动态新增) |
| 兼容性 | 非常好,ES5 支持 | 较差,需 ES6+,低版本浏览器需要 polyfill 或降级处理 |
| 使用场景 | 小范围精确控制,如数据响应(早期的 Vue 2.x) | 大范围监控,比如数据代理、观察、封装库(Vue 3) |
举个小例子:
Object.defineProperty
const obj = {};
Object.defineProperty(obj, 'name', {
get() {
console.log('访问 name');
return '小明';
},
set(value) {
console.log('设置 name 为', value);
}
});
obj.name; // 访问 name
obj.name = '小红'; // 设置 name 为 小红
obj.age =10 // no
- ➔ 只能对
name这个属性起作用 - ➔ 不能动态监听后续加进来的其他属性
Proxy
const obj = {};
const proxyObj = new Proxy(obj, {
get(target, key) {
console.log(`访问属性 ${key}`);
return target[key];
},
set(target, key, value) {
console.log(`设置属性 ${key} 为 ${value}`);
target[key] = value;
return true;
}
});
proxyObj.name; // 访问属性 name
proxyObj.age = 18; // 设置属性 age 为 18
- ➔ 不管访问哪个属性,都能被统一拦截
- ➔ 支持监听新增的属性
- ➔ 能做更复杂的操作,比如验证、字段保护、虚拟属性等

浙公网安备 33010602011771号