Proxy可通过拦截get/set实现别名映射,即用一个属性名读写另一属性的数据;需定义aliasMap配置映射规则,handler中按规则转发操作,支持字符串直映射与函数式计算,兼顾默认行为与边界处理。

Proxy 可以通过拦截 get 和 set 操作,把对某个属性的访问或赋值,自动转发到另一个实际存在的属性上,从而实现“别名映射”——即用一个名字读写另一个名字背后的数据。
定义别名映射规则
先明确哪些属性是别名、对应哪个真实属性。例如让 fullName 作为 firstName 和 lastName 的组合别名,或让 color 映射到 bgColor。
推荐用一个配置对象描述映射关系,结构清晰、易于维护:
const aliasMap = {
fullName: { get: (obj) => `${obj.firstName} ${obj.lastName}`, set: (obj, val) => {
const [first, last] = val.split(' ');
obj.firstName = first;
obj.lastName = last;
}},
color: 'bgColor',
isActive: 'enabled'
};
在 handler 中处理 get/set 拦截
利用 Reflect.get 和 Reflect.set 保证默认行为,遇到别名时按规则转换:
- 如果读取的 key 在
aliasMap中且值为字符串,直接读取对应的真实属性 - 如果值为对象且含
get方法,调用它获取计算值 - 写入时同理:字符串映射直接赋值;带
set函数则执行自定义逻辑 - 其余情况走默认行为(
Reflect.get/set)
创建并使用 Proxy 实例
把原始对象和 handler 封装成 Proxy,外部代码即可透明使用别名:
const target = { firstName: 'John', lastName: 'Doe', bgColor: '#fff', enabled: true };
const handler = {
get(obj, prop) {
if (prop in aliasMap) {
const rule = aliasMap[prop];
if (typeof rule === 'string') return obj[rule];
if (typeof rule.get === 'function') return rule.get(obj);
}
return Reflect.get(obj, prop);
},
set(obj, prop, value) {
if (prop in aliasMap) {
const rule = aliasMap[prop];
if (typeof rule === 'string') obj[rule] = value;
else if (typeof rule.set === 'function') rule.set(obj, value);
return true;
}
return Reflect.set(obj, prop, value);
}
};
const proxy = new Proxy(target, handler);
console.log(proxy.fullName); // "John Doe"
proxy.fullName = 'Jane Smith';
console.log(proxy.firstName); // "Jane"
注意边界与扩展性
别名不等于新属性,in 操作符、Object.keys() 不会包含别名;如需枚举支持,可增强 ownKeys 和 has 拦截。
若需双向深度映射(比如嵌套对象别名),可在 get 返回值时递归代理,但要注意循环引用和性能开销。
不复杂但容易忽略:别名修改不应意外影响原始属性以外的状态,set 逻辑里避免副作用。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











