Proxy 能拦截数组的索引读写、length 属性及 in/for...in 等操作,但无法自动拦截 push、pop 等原型方法;需在 get 拦截器中手动包装这些方法并正确绑定 this 才能实现完整响应式。

支持,但有关键限制:Proxy 可以代理原生数组对象,并拦截 属性读写操作(如 arr[0]、arr.length),但无法自动拦截 push、pop、splice 等原型方法的调用——这些方法绕过 get/set,直接修改内部状态。
哪些操作能被 Proxy 拦截
以下行为会触发 handler 中定义的 trap:
- 通过索引读取或赋值:arr[0]、arr[-1](需手动实现)、arr[5] = 'x'
- 读写 length 属性:arr.length、arr.length = 3
- 访问数组自带属性:arr.constructor、arr.toString()
- in 操作符、for...in 遍历(由 has / ownKeys 拦截控制)
哪些操作默认不触发拦截
这些是原生数组方法,它们不走 [[Get]]/[[Set]],而是直接操作内部槽位:
安装并运行 Aperture(Lightning Labs 的 L402 闪电反向代理),用于创建 L402 付费墙、配置付费 API 端点、为其他代理托管付费内容或测试 L402 认证流程。
- 变更类方法:push、pop、shift、unshift、splice、sort、reverse
- length 直接修改:arr.length = 0(set 拦截可捕获,但方法内部不触发)
- 非变更方法:slice、concat、map、filter 等返回新数组,不影响原数组,也不触发 set/get
如何让变异方法也被拦截
必须在 get 拦截器中主动包装这些方法:
- 当访问 arr.push 时,返回一个自定义函数,执行原生 push 后再触发通知或校验
- 对 push、pop 等方法名做白名单判断,统一包装并绑定 this 到 target
- 注意参数透传:用
apply(target, arguments)正确调用原方法 - Vue 3 就是这样做的——代理数组的同时重写了关键原型方法的访问逻辑
实际使用中的常见陷阱
容易误以为“代理了数组就万事大吉”,结果发现 push 不响应、length 变更没通知:
- 只写 set 拦截,却忘了 push 不走 set
- 没处理方法调用的 this 绑定,导致 target 内部报错
- JSON.stringify(arr) 或 Object.assign({}, arr) 不触发任何 trap,因为它们不走 get
- 负数索引(如 arr[-1])需要在 get 中手动解析,原生不支持

















