50+Vue经典面试题源码级详解(46):Vue3.0里为什么要用 Proxy 替代 defineProperty

持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第23天,点击查看活动详情

前言

小伙伴们好,这是村长《Vue经典面试题源码级详解》系列文章第 46 题,前面已完成题目合集在此: 历时一个月,2.6W字!50+Vue经典面试题源码级详解,你值得收藏!

学习群

我组织了一个面试学习群,关注村长公众号村长学前端,回复“加群”,大家一起卷~

相关学习资源

本系列有配套视频思维导图开源项目,大家学习同时千万不要忘了三连 + 关注 + 分享,有道是喝水不忘挖井人~

Vue3.0里为什么要用 Proxy 替代 defineProperty ?

分析

Vue3中最重大的更新之一就是响应式模块reactivity的重写。主要的修改就是Proxy替换defineProperty实现响应式。

此变化主要是从性能方面考量。

思路

  • 属性拦截的几种方式
  • defineProperty的问题
  • Proxy的优点
  • 其他考量

回答范例

  • JS中做属性拦截常见的方式有三:: definePropertygetter/settersProxies.
  • Vue2中使用defineProperty的原因是,2013年时只能用这种方式。由于该API存在一些局限性,比如对于数组的拦截有问题,为此vue需要专门为数组响应式做一套实现。另外不能拦截那些新增、删除属性;最后defineProperty方案在初始化时需要深度递归遍历待处理的对象才能对它进行完全拦截,明显增加了初始化的时间。
  • 以上两点在Proxy出现之后迎刃而解,不仅可以对数组实现拦截,还能对Map、Set实现拦截;另外Proxy的拦截也是懒处理行为,如果用户没有访问嵌套对象,那么也不会实施拦截,这就让初始化的速度和内存占用都改善了。
  • 当然Proxy是有兼容性问题的,IE完全不支持,所以如果需要IE兼容就不合适

知其所以然

Proxy属性拦截的原理:利用get、set、deleteProperty这三个trap实现拦截

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) {}
    })
}

很容易看出两者的区别!

猜你喜欢

转载自juejin.im/post/7113801593291538462