You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用Proxy与Reflect代理Map时size属性报错的原因

为什么代理Map时仅访问size属性会报错?

我知道Map集合拥有[[MapData]]内部槽,因此尝试用Reflect配合Proxy进行拦截,编写了如下代码:

const map = new Map();

const proxiedMap = new Proxy(map, {
 get(target, property, receiver) {
  const currentValue = Reflect.get(target, property, receiver);
  return typeof currentValue === "function" ? currentValue.bind(target) : currentValue;
 }
});

调用set和get方法时代码运行正常,但访问size属性时抛出错误:

proxiedMap.set("a", 1);
proxiedMap.get("a"); // 1
console.log(proxiedMap.size) // TypeError: Method get Map.prototype.size called on incompatible receiver #<Map>

我通过省略Reflect中的receiver参数解决了问题,但不清楚原因:

const proxiedMap = new Proxy(map, {
  get(target, property) {
    const currentValue = Reflect.get(target, property)
    return typeof currentValue === "function" ? currentValue.bind(target) : currentValue
  }
})

问题原因解析

  • Map的size是访问器属性,它的getter函数会直接访问Map实例的[[MapData]]内部槽,而这个内部槽只能被原始的Map实例访问,代理对象并没有这个内部槽。
  • 当你在Reflect.get中传递receiver参数时,size的getter函数的this会指向receiver(也就是代理对象proxiedMap)。此时getter尝试从代理对象上读取[[MapData]],自然会触发"不兼容接收器"的错误。
  • 而set、get这些Map方法之所以没问题,是因为你在拦截时把它们绑定到了原始target(即真实的Map实例)上,调用这些方法时this始终指向原始Map,能正常访问内部槽。
  • 省略receiver参数后,Reflect.get默认会把target作为this上下文执行size的getter,此时getter的this是原始Map实例,能正常读取[[MapData]],所以不会报错。

内容的提问来源于stack exchange,提问作者LeeJaeyun

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.18 13:42:14