JavaScript Proxy实战:5个高级元编程技巧
1. 基础属性拦截
实现属性访问日志记录:
const user = {
name: '张三',
age: 30
};
const userProxy = new Proxy(user, {
get(target, prop) {
console.log(`访问属性: ${prop}`);
return target[prop];
},
set(target, prop, value) {
console.log(`设置属性: ${prop} = ${value}`);
target[prop] = value;
return true;
}
});
// 使用
console.log(userProxy.name); // 记录访问日志
userProxy.age = 31; // 记录设置日志
2. 数据验证代理
实现表单数据自动验证:
function createValidator(target, validator) {
return new Proxy(target, {
set(target, prop, value) {
if (validator[prop] && !validator[prop](value)) {
throw new Error(`无效的${prop}值: ${value}`);
}
target[prop] = value;
return true;
}
});
}
const userValidator = {
name: val => val.length >= 2,
age: val => val >= 18 && val <= 120
};
const validUser = createValidator({}, userValidator);
validUser.name = "李四"; // 成功
validUser.age = 17; // 抛出错误
3. 数组负索引支持
扩展数组功能:
function createNegativeArray(array) {
return new Proxy(array, {
get(target, prop) {
const index = parseInt(prop);
if (index < 0) {
return target[target.length + index];
}
return target[prop];
}
});
}
const arr = createNegativeArray(['a', 'b', 'c', 'd']);
console.log(arr[-1]); // 输出: 'd'
4. 自动缓存代理
实现方法结果缓存:
function cacheProxy(target) {
const cache = new Map();
return new Proxy(target, {
apply(target, thisArg, args) {
const key = JSON.stringify(args);
if (cache.has(key)) {
console.log('从缓存获取结果');
return cache.get(key);
}
const result = target.apply(thisArg, args);
cache.set(key, result);
return result;
}
});
}
const heavyCompute = cacheProxy(function(n) {
console.log('执行复杂计算...');
return n * n;
});
heavyCompute(5); // 执行计算
heavyCompute(5); // 从缓存获取
技术 | Object.defineProperty | Proxy |
---|---|---|
拦截能力 | 有限 | 全面 |
性能 | 较高 | 稍低 |
适用场景 | 简单拦截 | 复杂控制 |
5. 动态属性代理
实现动态属性生成:
const dynamicProperties = {
prefix: 'item_',
count: 0
};
const dynamicProxy = new Proxy(dynamicProperties, {
get(target, prop) {
if (prop in target) {
return target[prop];
}
const newProp = `${target.prefix}${target.count++}`;
target[prop] = newProp;
return newProp;
}
});
console.log(dynamicProxy.user); // item_0
console.log(dynamicProxy.product); // item_1
JavaScript Proxy为对象操作提供了强大的元编程能力,特别适合实现数据绑定、验证、缓存等高级功能。