10.1 使用 Proxy 拦截对象操作
10.1 使用 Proxy 拦截对象操作
Proxy 是 ES6 引入的一种元编程特性,允许你创建一个代理对象,用于拦截和自定义对目标对象的操作。通过 Proxy,你可以实现数据绑定、验证、日志记录等功能。本节将详细介绍 Proxy 的用法及其应用场景。
10.1.1 Proxy 的基本概念
Proxy 用于创建一个代理对象,拦截对目标对象的操作。它接受两个参数:
- 目标对象(Target):被代理的对象。
- 处理器对象(Handler):定义拦截操作的陷阱(Trap)。
1. 创建 Proxy
const target = {
name: "Alice",
age: 25,
};
const handler = {
get(target, prop) {
console.log(`Getting property: ${prop}`);
return target[prop];
},
set(target, prop, value) {
console.log(`Setting property: ${prop} to ${value}`);
target[prop] = value;
return true; // 表示设置成功
},
};
const proxy = new Proxy(target, handler);
console.log(proxy.name); // 输出 "Getting property: name" 和 "Alice"
proxy.age = 26; // 输出 "Setting property: age to 26"
10.1.2 常见的陷阱(Trap)
处理器对象可以定义多种陷阱,用于拦截不同的操作。
1. get
拦截属性的读取操作。
const handler = {
get(target, prop) {
console.log(`Getting property: ${prop}`);
return target[prop];
},
};
2. set
拦截属性的设置操作。
const handler = {
set(target, prop, value) {
console.log(`Setting property: ${prop} to ${value}`);
target[prop] = value;
return true; // 表示设置成功
},
};
3. has
拦截 in 操作符。
const handler = {
has(target, prop) {
console.log(`Checking property: ${prop}`);
return prop in target;
},
};
console.log("name" in proxy); // 输出 "Checking property: name" 和 true
4. deleteProperty
拦截 delete 操作符。
const handler = {
deleteProperty(target, prop) {
console.log(`Deleting property: ${prop}`);
delete target[prop];
return true; // 表示删除成功
},
};
delete proxy.age; // 输出 "Deleting property: age"
10.1.3 Proxy 的应用场景
1. 数据绑定
通过 Proxy 实现数据绑定,自动更新视图。
const data = { name: "Alice" };
const handler = {
set(target, prop, value) {
target[prop] = value;
console.log(`View updated: ${prop} = ${value}`);
return true;
},
};
const proxy = new Proxy(data, handler);
proxy.name = "Bob"; // 输出 "View updated: name = Bob"
2. 数据验证
通过 Proxy 实现数据验证,确保数据的合法性。
const user = { age: 25 };
const handler = {
set(target, prop, value) {
if (prop === "age" && typeof value !== "number") {
throw new TypeError("Age must be a number");
}
target[prop] = value;
return true;
},
};
const proxy = new Proxy(user, handler);
proxy.age = 26; // 正常设置
proxy.age = "26"; // 抛出错误:Age must be a number
3. 日志记录
通过 Proxy 记录对象的操作日志。
const target = { name: "Alice" };
const handler = {
get(target, prop) {
console.log(`Getting property: ${prop}`);
return target[prop];
},
set(target, prop, value) {
console.log(`Setting property: ${prop} to ${value}`);
target[prop] = value;
return true;
},
};
const proxy = new Proxy(target, handler);
console.log(proxy.name); // 输出 "Getting property: name" 和 "Alice"
proxy.name = "Bob"; // 输出 "Setting property: name to Bob"
10.1.4 示例代码
示例 1:数据绑定
const data = { name: "Alice" };
const handler = {
set(target, prop, value) {
target[prop] = value;
console.log(`View updated: ${prop} = ${value}`);
return true;
},
};
const proxy = new Proxy(data, handler);
proxy.name = "Bob"; // 输出 "View updated: name = Bob"
示例 2:数据验证
const user = { age: 25 };
const handler = {
set(target, prop, value) {
if (prop === "age" && typeof value !== "number") {
throw new TypeError("Age must be a number");
}
target[prop] = value;
return true;
},
};
const proxy = new Proxy(user, handler);
proxy.age = 26; // 正常设置
proxy.age = "26"; // 抛出错误:Age must be a number
示例 3:日志记录
const target = { name: "Alice" };
const handler = {
get(target, prop) {
console.log(`Getting property: ${prop}`);
return target[prop];
},
set(target, prop, value) {
console.log(`Setting property: ${prop} to ${value}`);
target[prop] = value;
return true;
},
};
const proxy = new Proxy(target, handler);
console.log(proxy.name); // 输出 "Getting property: name" 和 "Alice"
proxy.name = "Bob"; // 输出 "Setting property: name to Bob"
10.1.5 总结
Proxy:用于创建代理对象,拦截对目标对象的操作。- 陷阱(Trap):如
get、set、has、deleteProperty等,用于拦截不同的操作。 - 应用场景:数据绑定、数据验证、日志记录等。
通过掌握 Proxy,你可以实现更灵活、更强大的对象操作拦截功能。在接下来的学习中,我们将继续探索 JavaScript 的其他高级特性。
思考题:
Proxy的主要作用是什么?- 如何使用
Proxy实现数据验证? - 在什么情况下应该使用
Proxy而不是直接操作对象?
#前端开发
分享于 2025-03-21