Vue响应式实现
大约 2 分钟
原理
Proxy
与Object.defineProperty
Proxy
Proxy
将代理一个对象(被代理对象),得到一个新的对象(代理对象),同时拥有被代理对象中所有的属性。- 当想要修改对象的指定属性时,我们应该使用代理对象进行修改
- 代理对象 的任何一个属性都可以触发
handler
的getter
和setter
Object.defineProperty
Object.defineProperty
为指定对象的指定属性设置属性描述符- 当想要修改对象的指定属性时,可以使用原对象进行修改
- 通过属性描述符,只有 被监听 的指定属性,才可以触发
getter
和setter
所以当 vue3 通过 Proxy 实现响应性核心 API 之后,vue 将 不会 再存在新增属性时失去响应性的问题。
Reflect
https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Reflect
Reflect
+Proxy
当我们期望监听代理对象的 getter 和 setter 时,不应该使用 target[key] ,因为它在某些时刻(比如 fullName)下是不可靠的。而 应该使用 Reflect ,借助它的 get 和 set 方法,使用receiver (proxy 实例) 作为 this,已达到期望的结果(触发三次 getter)
最后如果我们想要“安全”的使用Proxy,还需要配合Reflect一起才可以,因为一旦我们在被代理对象的内部,通过 this 触发 getter 和 setter 时,也需要被监听到。