Proxy 相比于 defineProperty 的优势

Vue 2 用 Object.defineProperty 劫持数据的 getter/setter,存在两个明显短板:

  1. 必须遍历对象的每个属性:对于深层嵌套的对象,需要递归遍历,性能开销较大。
  2. 无法监听数组变化:Vue 2 通过重写数组方法(push/pop/shift/unshift/splice/sort/reverse)来"打补丁"实现监听。
  3. 无法感知新增/删除属性:动态添加的属性需要用 Vue.set / Vue.delete 才能保持响应式。

Proxy 的优点:

  1. 代理整个对象:不需要遍历每个属性,对象任意嵌套层级都可拦截。
  2. 原生支持数组:直接拦截数组的 push、splice、索引访问等操作。
  3. 支持 13 种拦截操作:get/set/deleteProperty/has/ownKeys 等,新增/删除属性也能被监听到。

为什么 Vue 2.x 不使用 Proxy?

一个很重要的原因就是:

  • Proxy 是 ES6 提供的新特性,浏览器兼容性不好(特别是 IE),且该 API 无法用 polyfill 来兼容。
  • 在 Vue 2.x 发布时(2016 年),Proxy 的浏览器覆盖率还比较低,需要兼容旧版本浏览器。
  • Vue 3.x(2020 年发布)开始正式拥抱 Proxy,因为现代浏览器的兼容性已经足够。

来源整理自:vue3js.cn 面试官系列