js实现proxy
使用 Proxy 对象创建代理
Proxy 是 JavaScript 提供的一个强大功能,用于创建一个对象的代理,从而拦截和自定义对象的基本操作。通过 Proxy,可以拦截诸如属性读取、属性设置、函数调用等操作。
const target = {
name: 'John',
age: 30
};
const handler = {
get(target, property) {
console.log(`Getting property ${property}`);
return target[property];
},
set(target, property, value) {
console.log(`Setting property ${property} to ${value}`);
target[property] = value;
return true;
}
};
const proxy = new Proxy(target, handler);
拦截常见操作
Proxy 可以拦截多种操作,包括属性访问、赋值、删除、函数调用等。以下是一些常见的拦截器(traps):
const handler = {
get(target, prop) {
return prop in target ? target[prop] : 'Default';
},
set(target, prop, value) {
if (prop === 'age' && typeof value !== 'number') {
throw new Error('Age must be a number');
}
target[prop] = value;
return true;
},
deleteProperty(target, prop) {
if (prop in target) {
delete target[prop];
return true;
}
return false;
}
};
使用 Proxy 实现数据验证
Proxy 可以用于实现数据验证逻辑,确保对象的属性符合特定条件。
const validator = {
set(target, key, value) {
if (key === 'age') {
if (typeof value !== 'number' || value < 0 || value > 120) {
throw new Error('Invalid age');
}
}
target[key] = value;
return true;
}
};
const person = new Proxy({}, validator);
person.age = 25; // 正常
person.age = '25'; // 抛出错误
使用 Proxy 实现函数调用的拦截
Proxy 不仅可以拦截对象的属性操作,还可以拦截函数的调用。
function sum(a, b) {
return a + b;
}
const handler = {
apply(target, thisArg, argumentsList) {
console.log(`Function called with arguments: ${argumentsList}`);
return target(...argumentsList) * 2;
}
};
const proxySum = new Proxy(sum, handler);
console.log(proxySum(1, 2)); // 输出: Function called with arguments: 1,2 然后输出 6
使用 Proxy 实现私有属性
Proxy 可以用于模拟私有属性,防止外部直接访问某些属性。
const privateData = {
_secret: 'This is private',
publicData: 'This is public'
};
const handler = {
get(target, prop) {
if (prop.startsWith('_')) {
throw new Error('Access to private property is denied');
}
return target[prop];
},
set(target, prop, value) {
if (prop.startsWith('_')) {
throw new Error('Access to private property is denied');
}
target[prop] = value;
return true;
}
};
const proxyData = new Proxy(privateData, handler);
console.log(proxyData.publicData); // 正常
console.log(proxyData._secret); // 抛出错误
使用 Proxy 实现对象观察者模式
Proxy 可以用于实现观察者模式,监听对象的变化并触发回调。
function observe(target, callback) {
return new Proxy(target, {
set(target, key, value) {
const oldValue = target[key];
target[key] = value;
callback(key, oldValue, value);
return true;
}
});
}
const user = observe({}, (key, oldValue, newValue) => {
console.log(`Property ${key} changed from ${oldValue} to ${newValue}`);
});
user.name = 'Alice'; // 输出: Property name changed from undefined to Alice
使用 Proxy 实现负索引数组
Proxy 可以用于扩展数组的功能,例如支持负索引访问。
const negativeArray = (arr) => new Proxy(arr, {
get(target, prop) {
const index = parseInt(prop);
if (index < 0) {
return target[target.length + index];
}
return target[prop];
}
});
const arr = negativeArray([1, 2, 3, 4, 5]);
console.log(arr[-1]); // 输出 5
console.log(arr[-2]); // 输出 4
注意事项
Proxy 虽然强大,但需要注意以下几点:

- 某些操作可能无法被拦截,例如使用
Object.keys()或for...in循环。 - Proxy 的性能开销比直接操作对象略高,因此在性能敏感的场景中需谨慎使用。
- 某些 JavaScript 内置方法可能无法正确处理 Proxy 对象。






