js实现proxy
使用 Proxy 对象的基本方法
在 JavaScript 中,Proxy 对象用于创建一个对象的代理,从而实现对基本操作的拦截和自定义。Proxy 可以拦截诸如属性读取、属性设置、函数调用等操作。
const target = {
name: 'John',
age: 30
};
const handler = {
get: function(target, prop) {
return prop in target ? target[prop] : 'Property not found';
},
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 proxy = new Proxy(target, handler);
console.log(proxy.name); // 'John'
console.log(proxy.unknown); // 'Property not found'
proxy.age = 35; // 正常设置
proxy.age = 'thirty'; // 抛出 TypeError
拦截不同操作
Proxy 可以拦截多种操作,包括但不限于属性访问、赋值、函数调用等。以下是一些常见的拦截操作示例:

const handler = {
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;
},
deleteProperty(target, prop) {
console.log(`Deleting property ${prop}`);
delete target[prop];
return true;
},
apply(target, thisArg, argumentsList) {
console.log(`Function called with arguments: ${argumentsList}`);
return target.apply(thisArg, argumentsList);
}
};
const obj = { a: 1 };
const proxyObj = new Proxy(obj, handler);
proxyObj.a; // 触发 get
proxyObj.b = 2; // 触发 set
delete proxyObj.a; // 触发 deleteProperty
const func = (x, y) => x + y;
const proxyFunc = new Proxy(func, handler);
proxyFunc(1, 2); // 触发 apply
使用 Proxy 实现数据验证
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 > 120) {
throw new RangeError('Age must be between 0 and 120');
}
}
target[prop] = value;
return true;
}
};
const person = new Proxy({}, validator);
person.age = 25; // 正常设置
person.age = 'twenty-five'; // 抛出 TypeError
person.age = 150; // 抛出 RangeError
使用 Proxy 实现私有属性
通过 Proxy 可以模拟私有属性,防止外部直接访问或修改某些属性:
const privateProps = new WeakMap();
const handler = {
get(target, prop) {
if (prop.startsWith('_')) {
throw new Error(`Access to private property ${prop} is denied`);
}
return target[prop];
},
set(target, prop, value) {
if (prop.startsWith('_')) {
throw new Error(`Modification of private property ${prop} is denied`);
}
target[prop] = value;
return true;
}
};
const obj = { publicProp: 'public', _privateProp: 'private' };
const proxy = new Proxy(obj, handler);
console.log(proxy.publicProp); // 'public'
console.log(proxy._privateProp); // 抛出 Error
proxy._privateProp = 'new value'; // 抛出 Error
使用 Proxy 实现函数调用的日志记录
Proxy 可以用于记录函数的调用情况,包括参数和返回值:
function logFunctionCalls(target) {
return new Proxy(target, {
apply(target, thisArg, argumentsList) {
console.log(`Function called with arguments: ${argumentsList}`);
const result = target.apply(thisArg, argumentsList);
console.log(`Function returned: ${result}`);
return result;
}
});
}
function add(a, b) {
return a + b;
}
const loggedAdd = logFunctionCalls(add);
loggedAdd(2, 3); // 记录调用和返回值






