javascript不支持多重继承,但可通过proxy拦截get、has等trap,按序遍历多个源对象实现属性动态委托,并透传receiver确保getter中this指向代理本身,同时需重写getprototypeof、ownkeys等trap补全语义。

核心思路:用 get + receiver 做动态委托
Proxy 的 get(target, key, receiver) 是入口。receiver 是当前代理对象(即你调用 .xxx 时的 this),必须透传给 Reflect.get,否则 getter 内部的 this 会指向原始源对象,导致上下文错乱或响应式失效。
- 先检查实例自身是否拥有该属性(
prop in target) - 再按预设顺序遍历多个源对象(比如
[MixinA, MixinB, BaseClass]) - 对每个源对象,用
key in obj判断是否可访问(含原型链) - 一旦命中,立刻用
Reflect.get(obj, key, receiver)返回,确保 this 正确
光有 get 不够:还得补全语义操作
像 'method' in proxy、proxy instanceof MixinA 或 Object.keys(proxy) 这些操作,不会触发 get,必须显式拦截对应 trap:
- has:返回 true 只要任一源对象(含原型)有该 key
- getPrototypeOf:不能直接返回某个源的原型,得构造一个“合成原型代理”,它的 get 同样做多源查找
-
ownKeys 和 getOwnPropertyDescriptor:决定哪些属性出现在
Object.keys()或for...in中,需合并各源的自有属性
实际写法:一个最小可用结构
假设你有两个类实例 instA 和 instB,想让代理同时“继承”它们的方法:
const handler = {
get(target, prop, receiver) {
if (prop in target) return target[prop];
if (prop in instA) return Reflect.get(instA, prop, receiver);
if (prop in instB) return Reflect.get(instB, prop, receiver);
return undefined;
},
has(target, prop) {
return prop in target || prop in instA || prop in instB;
}
};
const proxy = new Proxy({}, handler);
这样 proxy.methodA() 就能调用 instA.methodA,且其中的 this 仍是 proxy。
注意边界和取舍
Proxy 方案是运行时委托,不是编译期继承,所以:
- 无法真正改变 instanceof 的底层行为(除非重写 getPrototypeOf 并配合 Symbol.hasInstance)
- 性能略低于原生访问,高频场景需权衡
- 同名属性按顺序覆盖——后声明的源优先,这点和 class extends 一致
- 如果只是静态组合,Mixin 拷贝更轻量;需要响应式或动态切换源时,Proxy 更合适
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











