写在前面
如果你对Vue发布订阅的响应式实现有一定的了解,那么你一定知道defineProperty
。
Object.defineProperty(obj, prop, descriptor)
Vue2.x中的响应式实现正是基于defineProperty
中的descriptor
,通过属性的getter、setter
监听来实现的。
同时你应该知道的是,我们在Vue
中使用下标的方式直接修改属性的值或者添加一个预先不存在的对象属性是无法做到setter
监听的,这是defineProperty
的局限性。
而我们在Vue中使用的push
、pop
、shift
、unshift
、splice
等一系列修改原数组的方法,其实不是原生的数组方法,都是被Vue修改过的,其中加入了响应代码。
defineProperty中的getter、setter
defineProperty
的局限性的最大原因是它只能针对单例属性做监听,Vue2.x
中对data
中的属性做了遍历 + 递归,为每个属性设置了getter
、setter
。
这也就是为什么Vue只能对data中预定义过的属性做出响应的原因。
Proxy中的getter、setter
Proxy
可以理解成,在目标对象之前架设一层“拦截”,外界对该对象的访问,都必须先通过这层拦截,因此提供了一种机制,可以对外界的访问进行过滤和改写。
也就是说,Proxy
的监听是针对一个对象的,那么对这个对象的所有操作会进入监听操作,这就完全可以代理所有属性了。
Proxy中getter、setter说明
get
接收三个参数: get(target, propKey, receiver)target
是被监听对象,在示例代码中表示的是data propKey是属性名,即当前需要获取的属性名 receiver是监听对象,即Proxy实例,在示例代码中表示的是proxyset
接收四个参数: get(target, propKey, value, receiver)
target
、propKey
、receiver
三个参数和get中一样 value表示被修改的值,即测试代码中的1
很明显的是,我们使用
Proxy
时并不需要关心某一个具体的属性,并且Proxy
实例上的修改不会影响到被监听对象target
中的值(前提是你不主动修改target
)。
评论区