vue3 为何要用proxy替换Object.defineProperty

javaScript es5 提供了Object.defineProperty方法,允许对对象的getter/settet进行拦截,该方法会直接在一个对象上定义一个新属性,或者修改现有属性并返回此对象。
我们可以理解为是针对对象上的某一个属性做处理的。

语法: Object.defineProperty(obj, prop, descriptor)

               * obj 要定义属性的对象

               * prop 要定义或修改的属性的名称或Symbol

               * descriptor 要定义或修改的属性描述符

            const obj = {}
            Object.defineProperty(obj, "a", {
                 value: 1,

                 writable: false,  // 是否可写
                 configurable: false  // 是否可配置
            })

 

vue3之前双向绑定都是由defineProperty来实现,3.0之后重构为proxy,他们的区别在哪里呢?

const obj = {};
Object.defineProperty(obj, 'a', {
  set(val) {
    console.log(`开始设置新值: ${val}`)
  },
  get() { 
    console.log(`开始读取属性`)
    return 1; 
  },
  writable : true
})

obj.a = 2 // 开始设置新值: 2
obj.a // 开始获取属性 

在vue中,当我们使用或者修改对象时,对应的get和set就会被执行,然后就会触发watch中关于这条数据的监听函数,从而更新视图

但是对象新增属性的时候视图时不更新的

因为data init 是在生命周期created之前的操作,会对data绑定一个观察者Observer,之后data中的字段更新都会通知依赖收集器 Dep 触发视图更新

回到defineProperty 本身,是对对象上的属性做操作,而非对象本身

在Observer data时,新增的属性并不存在,自然就不会有getter和setter,所以视图也就不更新

vue提供的全局$set 本质上也是给新增的属性手动observer

由于js限制,vue不能检测数组通过索引设置元素

虽然defineProperty支持通过索引修改数组项,但是尤大考虑到性能因素,摒弃了。

但是defineProperty做不到新增索引,所以就有了数组的变异方法

对比

  -- proxy 作为新标准将受到浏览器厂商重点持续的性能优化

  -- proxy 能观察的类型比defineProperty更丰富

  -- proxy 不兼容ie,也没有polyfill,defineProperty 能支持到ie9

  -- Object.defineProperty 是劫持对象的属性,新增元素需要再次defineProperty.而proxy劫持的是整个对象,不需要做特殊处理

  -- 使用defineProperty时,我们修改原来的obj对象就可以触发拦截,而使用proxy,就必须修改代理对象,即proxy的实例

 

参考文献 : https://vue3js.cn/es6/#%E6%AD%A3%E6%96%87

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值