为何Proxy与Object.create无法协同使用?
为什么console.log(receiver)会导致Proxy栈溢出?
问题原因
当执行derived.someProperty时,由于derived是通过Object.create(proxy6)创建的,它的原型指向proxy6这个Proxy实例。此时触发Proxy的get陷阱:
- 陷阱里执行
console.log(receiver),这里的receiver就是derived对象。 console.log在打印对象时,会自动读取对象的多个内置属性(比如toString、Symbol.toStringTag、__proto__等)来生成友好的输出格式。- 因为
derived的原型是Proxy,读取这些内置属性时,又会再次触发Proxy的get陷阱,陷阱里又会执行console.log(receiver),形成无限递归调用,最终超出调用栈上限,抛出RangeError: Maximum call stack size exceeded。
为什么这些操作能正常运行?
- 删掉
console.log(receiver):不会触发后续的属性读取递归,Proxy的get陷阱只执行一次,返回111后流程结束。 - 用
Object.assign({}, proxy6)包装Proxy:Object.assign会把Proxy的可枚举属性复制到新对象,新对象的原型是默认的Object.prototype,不再是Proxy实例。此时打印新对象时,读取内置属性只会走Object.prototype的逻辑,不会触发Proxy的get陷阱,自然不会递归。
原始复现代码
const someObject = {}; const proxy6 = new Proxy(someObject, { get(target, prop, receiver) { console.log(receiver); return 111; }, }); const derived = Object.create(proxy6); console.log(derived.someProperty);
内容的提问来源于stack exchange,提问作者Jack
相关产品推荐
相关产品推荐

