vue2为什么不用Object.defineProperty劫持数组

926 阅读1分钟

Object.defineProperty不能劫持数组么?

由于vue2.x文档上得一句话,普遍认为Object.defineProperty不能监听数组得变化,实际确并非如此

image.png

如下:

  var ary = [1,2]
  var temp = 0
  Object.defineProperty(ary,2,{
    configurable:true,
    set(value){
      temp = value
      console.log('变化了',value)
    },
    get(){
      console.log('获取值')
      return temp
    }
  })

当通过索引2修改/获取数组得值时,触发了监听

image.png

可见Object.defineProperty是可以监听数组变动的,但vue2为何没用使用它,儿选择改写数组得方法来实现对数组变化得监听?

vue2为什么选择改写数组的方法来实现对数组的监听

  • Object.defineProperty无法劫持数组长度length属性得变化,而数组length属性会影响数组的变动

    例如: 上面代码,设置数组长度length为0,ary[2]得值变成了undefined,但没有触发set,未监听到变动
    

    image.png

  • Object.defineProperty只能劫持已有属性,要监听数组变化,必须预设数组长度,遍历劫持,但数组长度在实际引用中是不可预料的

  • 数组删除新增会导致索引key发生变动,每次变动都需要重新遍历,添加劫持,数据量大时非常影响性能

     例如:如上代码删除数组第一个元素,ary[2]的监听失效了
    

    image.png

以上原因vue2抛弃了使用Object.defineProperty对数组的监听