JS Proxy 代理对象
理解 JavaScript Proxy 机制,通过拦截对象操作实现数据验证、日志记录、属性默认值等高级功能。 · 难度:入门 · +15XP
JavaScript Proxy 代理
Proxy 是 ES6 引入的强大特性,允许你创建一个对象的代理,从而拦截并自定义对该对象的基本操作(如属性读取、赋值、函数调用等)。
基本概念
创建一个 Proxy 需要两个参数:目标对象 target 和一个处理程序对象 handler。handler 中定义一组“陷阱”(trap),每个陷阱对应一种操作。
const target = { message: 'hello' };
const handler = {
get: function(obj, prop) {
return prop in obj ? obj[prop] : 属性 ${prop} 不存在;
}
};
const proxy = new Proxy(target, handler);
console.log(proxy.message); // 'hello'
console.log(proxy.unknown); // '属性 unknown 不存在'
常用陷阱
| 陷阱 | 触发时机 | 常见用途 |
|---|---|---|
get | 读取属性 | 默认值、日志、访问控制 |
set | 设置属性 | 数据验证、自动更新 |
has | in 操作符 | 隐藏属性 |
deleteProperty | delete 操作 | 防止删除 |
apply | 函数调用 | 函数拦截 |
实战:数据验证
const validator = {
set: function(obj, prop, value) {
if (prop === 'age') {
if (typeof value !== 'number' || value < 0) {
throw new TypeError('年龄必须是正数');
}
}
obj[prop] = value;
return true;
}
};
const user = new Proxy({}, validator);
user.age = 25; // 正常
user.age = -5; // 抛出错误
注意事项
- Proxy 是“透明”的,但
===不会穿透代理。 - 性能开销比直接操作对象稍大,不适合性能关键路径。
- 配合
ReflectAPI 使用更佳,Reflect提供了与陷阱一一对应的默认行为。
练习提示
创建一个 Proxy,实现以下功能:
1. 读取不存在的属性时返回默认值 'N/A'。
2. 设置属性时,如果值是字符串则自动去除首尾空格。
3. 禁止删除任何属性(删除时静默失败)。