js实现proxy
JavaScript 实现 Proxy
Proxy 是 JavaScript 中的一个强大特性,用于创建一个对象的代理,从而可以拦截和自定义对象的基本操作。以下是 Proxy 的基本实现方法和常见用法。
基本语法
Proxy 的构造函数接受两个参数:目标对象和处理程序对象。处理程序对象包含一组“陷阱”(traps),用于拦截对目标对象的操作。
const target = {};
const handler = {
get: function(target, property, receiver) {
return property in target ? target[property] : 'default';
}
};
const proxy = new Proxy(target, handler);
常见拦截操作
Proxy 可以拦截多种操作,以下是一些常见的陷阱方法:
get 陷阱 拦截对象属性的读取操作。
const handler = {
get(target, prop) {
return prop === 'name' ? 'Proxy User' : target[prop];
}
};
const proxy = new Proxy({}, handler);
console.log(proxy.name); // 输出: Proxy User
set 陷阱 拦截对象属性的设置操作。
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({}, handler);
proxy.age = 25; // 正常
proxy.age = '25'; // 抛出 TypeError
apply 陷阱 拦截函数的调用操作。
const handler = {
apply(target, thisArg, argumentsList) {
console.log(`Called with args: ${argumentsList}`);
return target.apply(thisArg, argumentsList);
}
};
function sum(a, b) {
return a + b;
}
const proxy = new Proxy(sum, handler);
console.log(proxy(1, 2)); // 输出: Called with args: 1,2 然后输出 3
实际应用示例
Proxy 可以用于数据验证、日志记录、性能监控等场景。
数据验证
const validator = {
set(target, prop, value) {
if (prop === 'age') {
if (!Number.isInteger(value)) {
throw new TypeError('Age must be an integer');
}
if (value < 0 || value > 150) {
throw new RangeError('Age must be between 0 and 150');
}
}
target[prop] = value;
return true;
}
};
const person = new Proxy({}, validator);
person.age = 30; // 正常
person.age = 'thirty'; // 抛出 TypeError
日志记录

const logger = {
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 obj = new Proxy({}, logger);
obj.name = 'Alice'; // 输出: Setting property "name" to "Alice"
console.log(obj.name); // 输出: Getting property "name" 然后输出 Alice
注意事项
- Proxy 的陷阱方法必须返回正确的值,否则可能导致错误。例如,
set陷阱必须返回一个布尔值。 - Proxy 不会改变原始对象的行为,只是通过代理对象拦截操作。
- 某些操作可能无法被拦截,例如使用
Object.keys()或for...in循环。
Proxy 提供了一种灵活的方式来控制和扩展对象的行为,适用于多种高级编程场景。






