vue2的实现(7)之数组劫持的考量

200 阅读2分钟

「这是我参与2022首次更文挑战的第14天,活动详情查看:2022首次更文挑战」。

vue2的实现(7)之数组劫持的考量

回顾

  • 上次内容我们处理了一个问题,我们把_data属性代理到了vm上,这样我们在取值的时候,就不需要从vm._data上取值了,只需要从vm上取值就可以了。下面是实现代码。
  • rewrite-vue/src/state.js
      import {observe} from './observe'
    
      export  function initState(vm) {
      const opts = vm.$options
    
    
          if (opts.data) {
          initData(vm)
          }
      }
    
    
      function initData(vm) {
          let data = vm.$options.data
          data = typeof data === 'function'? data.call(vm) : data
          vm._data = data
          proxy(vm, '_data')
          observe(data)
      } 
    
      function proxy(vm, target){
          for(let key in vm[target]){
              Object.defineProperty(vm,key,{
                  get(){
                      return vm[target][key]
                  },
                  set(newValue){
                      vm[target][key] = newValue
                  }
              })
          }
      }
    

数组劫持的考量

  • 我们用下面的代码测试一下,在浏览器打开rewrite-vue/dist/index.html

  • rewrite-vue/dist/index.html

      <!DOCTYPE html>
      <html>
      <head>
      <meta charset="UTF-8">
      <meta http-equiv="X-UA-Compatible" content="IE=edge">
      <meta name="viewport" content="width=device-width, initial-scale=1.0">
      <title>Vue2</title>
      </head>
      <body>
      <script src="./vue.js"></script>
      <script>
          const vm = new Vue({
            data:{
                name:'vue2',
                age: {
                  num:666,
                  key:'age'
                },
                arr:[1, 2, 3, 4, 5, 6, 7, 8, 9]
              }
          })
      </script>
      </body>
      </html>
    
  • 打开浏览器的控制台,我们对vm.arr做截取操作,vm.arr.splice(0,1)从第0个位置开始,截取1个元素。数组也是对象类型的数据,所以也会经过obser方法,循环遍历每个属性。我们对数据做截取操作,数组默认后面的元素,都会往前移一位,从下面的图片可以看到,我们截取了第一位,但是后面的每一个元素都会往前移动一位,所以后面的每个元素的getset方法都会触发,数组的第0个元素成了2。

  • 可想而知,当我们数组的长度很长的话,我们每次有改变原素组索引的操作,都会引起大量的getset方法执行,这样的话性能会很不好。

  • 回想我们对数组的操作,其实还是使用数组的原型上的方法比较多,直接通过索引的方式去操作数组的情况还是较少的。

    2022-01-31-1.png

  • 我们数组的方法中,其中改变原数组的方法有七个,分别是push unshift pop shift splice sort revers,所以Vue中对于数组的劫持主要还是通过重写数组原型上的方法来实现的。

往期精彩

今天是更文第十三天加油~

看到这里兄弟帮忙点个赞吧

vue2的实现(6)之将数据代理到Vue的实例上

vue2的实现(5)之对象劫持的一些细节处理二

vue2的实现(4)之对象劫持的一些细节处理一

vue2的实现(3)之对象的劫持

vue2的实现(2)之初始化数据data

vue2的实现(1)之搭建rollup打包环境

手撕koa,从零掌握koa的实现原理(1)

手撕koa,从零掌握koa的实现原理(2)

手撕koa,从零掌握koa的实现原理(3)

手撕koa,从零掌握koa的实现原理(4)

手撕koa,从零掌握koa的实现原理(5)

手撕koa,从零掌握koa的实现原理(6)

手撕koa,从零掌握koa的实现原理(7)