1. Proxy 与 Object.defineProperty 在 Vue 2/3 响应式系统的对比
Vue 2 与 Vue 3 分别使用 Object.defineProperty 与 Proxy 实现响应式,两者有何差异与取舍?
- Object.defineProperty 只能拦截已有属性(Vue 2)
- Proxy 可拦截任意属性增删、数组、Map/Set(Vue 3)
- 性能与兼容性取舍
Vue 2 用 Object.defineProperty 对对象属性做 getter/setter 改写,实现属性级拦截;其局限是只能拦截"已存在"的属性,新增/删除属性无法自动响应(需用 Vue.set/delete),数组的索引与 length 变更也难以拦截(需重写数组方法)。Vue 3 改用 Proxy 对整个对象做代理,可拦截 get、set、has、deleteProperty、ownKeys 等全部操作,因此能监听属性的新增、删除以及数组、Map/Set 等内置集合的变更,语义更完整。性能上 Proxy 无需逐属性递归改写,且采用惰性代理(访问时才递归),初始化和深层访问更高效;但 Proxy 是 ES6 能力,Vue 3 放弃了 IE 兼容。取舍总结:Vue 3 的 Proxy 表达力更强、性能更好、代码更简洁,代价是兼容性要求更高;Vue 2 的 defineProperty 兼容旧浏览器但需 Vue.set/delete 处理边界。工程上迁移到 Vue 3 后,新增/删除属性与数组操作无需再依赖特殊 API。
本题对比两种响应式实现的核心差异。回答要点出"defineProperty 只能拦截已有属性、需手动处理新增/删除与数组"与"Proxy 拦截全部操作、天然支持集合与增删"这一根本区别,并说明性能与兼容性的取舍。