Proxy
和 Object.defineProperty
都可以用来拦截和操作对象的属性访问,但它们在功能、灵活性和适用场景上有显著的区别。
1. Object.defineProperty
功能
- 用于定义或修改对象的属性,包括属性的值、可写性、可枚举性、可配置性等。
- 主要用于对单个属性进行细粒度的控制。
使用场景
- 对象属性的拦截和修改,例如:
- 定义 getter 和 setter。
- 修改属性的配置。
示例代码
const obj = {};
Object.defineProperty(obj, "name", {
value: "Alice",
writable: true,
enumerable: true,
configurable: true,
});
console.log(obj.name); // Alice
Object.defineProperty(obj, "name", {
get() {
return "Bob";
},
});
console.log(obj.name); // Bob
限制
- 只对定义的属性有效,不能拦截对对象的整体访问或操作。
- 需要针对每个属性分别进行定义,无法一次性处理多个属性或整个对象。
2. Proxy
功能
- 用于创建一个代理对象,该对象可以拦截并自定义对目标对象的基本操作(如属性访问、赋值、删除等)。
- 提供了更多的拦截能力和灵活性,支持对整个对象的操作。
使用场景
- 可以用来拦截和修改对象的所有操作,例如:
- 属性的读取、赋值、删除。
- 函数调用。
- 目标对象的创建和扩展。
示例代码
const target = {
name: "Alice",
};
const handler = {
get(target, property) {
return property in target ? target[property] : "Default";
},
set(target, property, value) {
target[property] = value.toUpperCase();
return true;
},
};
const proxy = new Proxy(target, handler);
console.log(proxy.name); // Alice
proxy.name = "Bob";
console.log(proxy.name); // BOB
console.log(proxy.age); // Default
优点
- 可以拦截对象的所有操作,提供更全面的控制。
- 可以动态地应用拦截逻辑,不需要修改原始对象的定义。