js Proxy实现
Proxy 基本概念
Proxy 是 ES6 引入的一个特性,用于创建一个对象的代理,从而拦截和自定义对象的底层操作。通过 Proxy,可以拦截对象的各种操作,如属性读取、属性设置、函数调用等。
创建 Proxy
Proxy 的构造函数接受两个参数:目标对象和处理程序对象。
const target = {};
const handler = {
get: function(target, prop, receiver) {
return prop in target ? target[prop] : 'default';
}
};
const proxy = new Proxy(target, handler);
常用拦截操作
get 拦截
拦截对象的属性读取操作。
const handler = {
get: function(target, prop) {
console.log(`Reading property ${prop}`);
return target[prop];
}
};
set 拦截
拦截对象的属性设置操作。
const handler = {
set: function(target, prop, value) {
console.log(`Setting property ${prop} to ${value}`);
target[prop] = value;
return true;
}
};
apply 拦截
拦截函数的调用操作。
const handler = {
apply: function(target, thisArg, argumentsList) {
console.log(`Calling function with args: ${argumentsList}`);
return target.apply(thisArg, argumentsList);
}
};
construct 拦截
拦截 new 操作符。
const handler = {
construct: function(target, argumentsList, newTarget) {
console.log(`Constructing with args: ${argumentsList}`);
return new target(...argumentsList);
}
};
实际应用示例
数据验证
const validator = {
set: function(target, prop, value) {
if (prop === 'age' && typeof value !== 'number') {
throw new TypeError('Age must be a number');
}
target[prop] = value;
return true;
}
};
const person = new Proxy({}, validator);
日志记录
const logger = {
get: function(target, prop) {
console.log(`Accessing property: ${prop}`);
return target[prop];
},
set: function(target, prop, value) {
console.log(`Setting property: ${prop} = ${value}`);
target[prop] = value;
return true;
}
};
const obj = new Proxy({}, logger);
负数组索引
const negativeArray = (array) => {
return new Proxy(array, {
get: function(target, prop, receiver) {
const index = parseInt(prop);
if (index < 0) {
prop = target.length + index;
}
return Reflect.get(target, prop, receiver);
}
});
};
const arr = negativeArray([1, 2, 3]);
console.log(arr[-1]); // 3
注意事项
Proxy 的某些拦截操作需要返回特定值,如 set 操作需要返回布尔值表示是否设置成功。不正确的返回值可能导致错误。
Proxy 只能代理对象,不能代理原始值。如果尝试代理原始值,会抛出 TypeError。

Proxy 的拦截操作不是所有对象操作都能捕获,如某些内置方法可能绕过 Proxy 的拦截。






