Object.defineProperty

0 阅读1分钟
  • Object.defineProperty:JS 用来“在对象某个属性上定义 getter/setter”的底层 API。Vue2 用它把每个字段变成“被访问会收集依赖、被修改会触发更新”。
1.拦截范围

defineProperty:只能拦截某个已存在属性的 get/set

2.新增/删除属性

defineProperty(Vue2):新增/删除属性默认监听不到(所以有 Vue.set / this.$set、Vue.delete)

3.数组响应式

defineProperty(Vue2):对数组要做很多“方法重写/补丁”(push/pop/splice 等)来触发更新;直接改索引曾经是坑点之一

4.性能与实现复杂度

defineProperty:需要递归把每个属性都“改造成 getter/setter”,对象大时初始化成本高

5.兼容性

defineProperty:兼容更老的浏览器(Vue2 能支持 IE)

小案例:新增属性这一点最直观:

// defineProperty 拦不到“后来新增的 key”(Vue2 时代需要 Vue.set)
const obj = {}
obj.a = 1 // 这一步如果没提前 defineProperty,是无法自动变成响应式的