Vue3.0里为什么要用Proxy代替defineProperty?
分析:
Vue3中最大的更新之一就是响应模块reactivity的重写。主要的修改就是Proxy代替defineProperty实现响应式,此变化主要是从性能方面考量。
思路:
- 属性拦截的几种方式
- defineProperty的问题
- Proxy的优点
- 其他考量
分析:
- JS中属性拦截常见的方式有三:defineProperty,getter / setters和Proxies
- Vue2.0中使用defineProperty的原因是,2013年时只能用这种方式,由于该API存在一些局限性,比如对于数组的拦截有问题,为此vue需要专门为数组响应做一套实现。另外不能拦截那些新增、删除属性;最后defineProperty方案在初始化时需要深度递归遍历待处理的对象才能对它进行完全拦截,明显增加了初始化的时间
- 以上俩点Proxy出现之后迎刃而解,不仅可以对数组进行拦截,还能对Map,Set实现拦截;另外Proxy的拦截也是懒处理行为,如果用户没有访问嵌套对象,那么也不会拦截,这就让初始化的速度和内存占用都改善了。
- 当然Proxy是有兼容性问题的,IE完全不支持,所有如果需要IIE兼容就不合适。
Proxy属性拦截的原理:
利用get、set、deleteProperty这三个tarp实现拦截
function reactive(obj){
return new Proxy(obj,{
get(target,key){},
set(target,key,val){},
deleteProperty(target,key){},
})
}
Object.defineProperty属性拦截的原理:
利用get、set这俩个trap实现拦截
function defineReactive(obj,key,val){
Object.defineReactive(obj,key,{
get(key){},
set(key,val){}
})
}