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

JavaScript代理'get' TypeError错误含义解析及相关疑问解答

彻底解读这个Proxy的TypeError错误

你是不是看到这个错误一脸困惑?明明返回的和预期都是数组,为啥JS还揪着不放?而且代理不就是用来改返回值的吗?别着急,咱们一步步拆解这个问题:

错误信息的核心含义

先把这条错误拆成两部分看:

TypeError: 'get' on proxy: property 'items' is a read-only and non-configurable data property on the proxy target but the proxy did not return its actual value (expected '[object Array]' but got '[object Array]')

  1. 前半段:明确告诉你目标对象上的items属性是个被完全锁死的属性——它通过Object.defineProperty或类似方式设置了writable: false(只读,不能直接修改值)和configurable: false(不可配置,不能修改属性描述符、不能删除属性)。
  2. 后半段:你的代理get陷阱返回的不是这个属性的原始值,哪怕看起来都是数组,但JS判定两者不是同一个东西(因为是不同的引用)。

为什么代理不能随便改这个返回值?

这是ES规范给Proxy的get陷阱定的硬规则:

如果目标属性是不可配置且只读的数据属性,那么get陷阱的返回值必须和目标属性的原始值严格相等(===)。

为啥要搞这个规则?因为这类属性是开发者明确“锁死”的,意味着这个属性的取值是固定、不可篡改的。如果代理能随便返回别的值,就破坏了原本的属性契约——毕竟你都把属性设成只读不可配置了,就是不想让它变,代理要是偷偷改了,就违背了这个设计意图。

举个实际例子一看就懂:

// 先创建一个带锁死属性的目标对象
const target = {};
Object.defineProperty(target, 'items', {
  value: [], // 原始数组
  writable: false,
  configurable: false
});

// 错误的代理:返回了一个新的空数组
const badProxy = new Proxy(target, {
  get(target, prop) {
    if (prop === 'items') return []; // 这里返回的是新数组,和原始引用不一样
    return Reflect.get(...arguments);
  }
});

console.log(badProxy.items); // 直接触发你看到的那个错误!

// 正确的代理:返回原始值的引用
const goodProxy = new Proxy(target, {
  get(target, prop) {
    if (prop === 'items') return target.items; // 返回原始数组的引用,和目标值严格相等
    return Reflect.get(...arguments);
  }
});

console.log(goodProxy.items); // 正常输出,不会报错

为啥类型一致还报错?

你注意到错误里说“expected '[object Array]' but got '[object Array]'”,这是因为JS里引用类型的相等是引用相等,不是值相等。你返回的新数组[]和目标上的原始数组[]是两个完全不同的对象,哪怕它们的类型、内容都一样,===比较的结果也是false。JS就是因为这个,判定你返回的不是“实际值”,所以报错。

总结一下

这个错误的本质是:你违反了Proxy的规范约束——对于不可配置且只读的目标属性,get陷阱必须返回属性的原始值(严格相等),不能返回任何替代值,哪怕替代值看起来和原始值一模一样。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.04 09:50:38