纯js实现代理
纯 JavaScript 实现代理
在 JavaScript 中,可以使用 Proxy 对象来创建代理,用于拦截和自定义对象的基本操作。Proxy 允许拦截对象的属性访问、赋值、枚举等操作。
基本代理实现
创建一个简单的代理,拦截对象的属性访问和赋值操作:
const target = {
name: 'Alice',
age: 25
};
const handler = {
get(target, property) {
console.log(`访问属性: ${property}`);
return target[property];
},
set(target, property, value) {
console.log(`设置属性: ${property} = ${value}`);
target[property] = value;
return true;
}
};
const proxy = new Proxy(target, handler);
console.log(proxy.name); // 访问属性: name → Alice
proxy.age = 30; // 设置属性: age = 30
拦截更多操作
Proxy 可以拦截多种操作,例如 deleteProperty、has(in 操作符)、ownKeys(Object.keys)等:

const handler = {
get(target, prop) {
if (prop in target) {
return target[prop];
}
return `属性 ${prop} 不存在`;
},
deleteProperty(target, prop) {
console.log(`删除属性: ${prop}`);
delete target[prop];
return true;
},
has(target, prop) {
console.log(`检查属性是否存在: ${prop}`);
return prop in target;
}
};
const proxy = new Proxy({ name: 'Bob' }, handler);
console.log(proxy.age); // 属性 age 不存在
delete proxy.name; // 删除属性: name
console.log('name' in proxy); // 检查属性是否存在: name → false
函数代理
Proxy 也可以代理函数,拦截函数的调用操作:
const handler = {
apply(target, thisArg, argumentsList) {
console.log(`调用函数,参数: ${argumentsList}`);
return target(...argumentsList) * 2;
}
};
function sum(a, b) {
return a + b;
}
const proxy = new Proxy(sum, handler);
console.log(proxy(2, 3)); // 调用函数,参数: 2,3 → 10
验证代理
代理可以用于验证对象的属性赋值,例如确保年龄是正数:

const validator = {
set(target, prop, value) {
if (prop === 'age') {
if (typeof value !== 'number' || value <= 0) {
throw new Error('年龄必须是正数');
}
}
target[prop] = value;
return true;
}
};
const person = new Proxy({}, validator);
person.age = 25; // 正常
person.age = -5; // 抛出错误: 年龄必须是正数
代理的撤销
Proxy.revocable 可以创建一个可撤销的代理,后续可以通过调用 revoke 方法撤销代理:
const { proxy, revoke } = Proxy.revocable({ name: 'Charlie' }, {
get(target, prop) {
return `属性 ${prop}: ${target[prop]}`;
}
});
console.log(proxy.name); // 属性 name: Charlie
revoke();
console.log(proxy.name); // 抛出错误: Cannot perform 'get' on a proxy that has been revoked
实际应用场景
代理在实际开发中有多种用途,例如:
- 数据验证和格式化
- 日志记录和调试
- 性能监控
- 实现观察者模式
const observable = (obj) => {
return new Proxy(obj, {
set(target, prop, value) {
console.log(`属性 ${prop} 从 ${target[prop]} 变为 ${value}`);
target[prop] = value;
return true;
}
});
};
const user = observable({ name: 'Dave' });
user.name = 'Eve'; // 属性 name 从 Dave 变为 Eve
通过 Proxy,可以灵活地拦截和自定义对象的操作,为 JavaScript 开发提供更多可能性。






