纯js实现代理
纯 JavaScript 实现代理
在 JavaScript 中,可以通过 Proxy 对象实现代理模式。Proxy 用于创建一个对象的代理,从而拦截和自定义对象的底层操作。
基本代理实现
创建一个简单的代理,拦截对象的属性访问和赋值操作:
const target = {
name: 'Alice',
age: 25
};
const handler = {
get(target, property) {
console.log(`Accessed property: ${property}`);
return target[property];
},
set(target, property, value) {
console.log(`Set property ${property} to ${value}`);
target[property] = value;
return true;
}
};
const proxy = new Proxy(target, handler);
console.log(proxy.name); // 输出: Accessed property: name, Alice
proxy.age = 30; // 输出: Set property age to 30
验证代理
通过代理可以实现属性验证,确保赋值的合法性:

const validator = {
set(target, property, value) {
if (property === 'age' && typeof value !== 'number') {
throw new TypeError('Age must be a number');
}
target[property] = value;
return true;
}
};
const validatedProxy = new Proxy(target, validator);
validatedProxy.age = 'thirty'; // 抛出 TypeError: Age must be a number
函数代理
代理也可以用于函数,拦截函数的调用:
function greet(name) {
return `Hello, ${name}!`;
}
const functionHandler = {
apply(target, thisArg, argumentsList) {
console.log(`Called with arguments: ${argumentsList}`);
return target.apply(thisArg, argumentsList);
}
};
const proxiedGreet = new Proxy(greet, functionHandler);
console.log(proxiedGreet('Alice')); // 输出: Called with arguments: Alice, Hello, Alice!
隐藏私有属性
通过代理可以隐藏对象的私有属性:

const privateData = {
_secret: 'confidential',
publicInfo: 'Open to all'
};
const privacyHandler = {
get(target, property) {
if (property.startsWith('_')) {
return undefined;
}
return target[property];
},
has(target, property) {
return !property.startsWith('_') && property in target;
}
};
const privateProxy = new Proxy(privateData, privacyHandler);
console.log(privateProxy._secret); // 输出: undefined
console.log(privateProxy.publicInfo); // 输出: Open to all
console.log('_secret' in privateProxy); // 输出: false
链式操作代理
通过代理可以实现链式操作:
const chainableTarget = {
value: 1,
add(num) {
this.value += num;
return this;
},
subtract(num) {
this.value -= num;
return this;
}
};
const chainHandler = {
get(target, property) {
const value = target[property];
if (typeof value === 'function') {
return function(...args) {
const result = value.apply(target, args);
return result === target ? proxy : result;
};
}
return value;
}
};
const chainProxy = new Proxy(chainableTarget, chainHandler);
chainProxy.add(5).subtract(2).add(3);
console.log(chainProxy.value); // 输出: 7
注意事项
使用 Proxy 时需要注意以下几点:
- 代理的行为完全由 handler 对象定义,未定义的陷阱会直接转发到目标对象。
Proxy.revocable()可以创建可撤销的代理,通过调用返回的revoke函数可以取消代理。- 某些操作可能无法被代理拦截,如
Date.prototype.getTime()。 - 过度使用代理可能导致性能问题,特别是在频繁操作的热点代码中。
通过合理使用 Proxy,可以实现数据绑定、验证、日志记录、自动填充对象等多种高级功能。






