• vue源码解析之observe


    一. vue文档中有“由于 JavaScript 的限制,Vue 不能检测以下数组的变动”,是否真是由于JavaScript的限制,还是出于其他原因考虑

    1. 当你利用索引直接设置一个数组项时,例如:vm.items[indexOfItem] = newValue
    2. 当你修改数组的长度时,例如:vm.items.length = newLength

      第一种情况是利用索引设置一个数组项,经过试验索引是可以设置为响应式的,再去vue源码中看看是怎么实现的,代码是在core/observer/index.js中

    if (Array.isArray(value)) {
          if (hasProto) {
            protoAugment(value, arrayMethods)
          } else {
            copyAugment(value, arrayMethods, arrayKeys)
          }
          this.observeArray(value)
        } else {
          this.walk(value)
        }
    
    walk (obj: Object) {
        const keys = Object.keys(obj)
        for (let i = 0; i < keys.length; i++) {
          defineReactive(obj, keys[i])
        }
      }
    
    observeArray (items: Array<any>) {
        for (let i = 0, l = items.length; i < l; i++) {
          observe(items[i])
        }
      }

    由上面代码可知源码中确实也是分开处理的,把数组遍历后对每一项进行观测

    为什么会这样呢,自己猜测是因为通过索引观测太不稳定了

    比如数组很多由变异操作,都会引起索引的巨大变化,比如排序、增加或者删除等

    删除中间数组项,它后面的索引都会发生变化,这不仅消耗性能,而且边界情况太多,可能大大增加vue核心的代码量。

    反而现在的代码最终都是按照对象去观测,处理规则一致

    总结下来如果强行去实现利用索引去设置数组项可以实现,但是付出和获得不成正比,衡量下就放弃了,可以说是衡量的结果,一定程度上也可以说是数组的索引特性造成的

      第二种情况,经过测试,用Object.defineProperty去重新定义length属性会报错,由此可知length属性在初始化时已经定义了,查看文档http://yanhaijing.com/es5/#367可知

    length 属性拥有的初始特性是 { [[Writable]]: true, [[Enumerable]]: false, [[Configurable]]: false }. 

    总结可知确实因为JavaScript 限制,当修改数据长度时不能观测到

  • 相关阅读:
    怎样跟踪来访用户?
    五个瓶颈影响你的Asp.Net程序(网站)性能
    if判断与比较操作符gt、lt、eq等的使用
    裸机LCD驱动配置
    汇编指令-位置无关码(BL)与绝对位置码(LDR)(2)
    汇编指令-MRS(读)和MSR(写)指令操作CPSR寄存器和SPSR寄存器使用(1)
    Nand Flash驱动(实现初始化以及读操作)
    makefile使用.lds链接脚本以及 $@ ,$^, $,< 解析
    makefile初步制作,arm-linux- (gcc/ld/objcopy/objdump)详解
    Liunx-常用命令杂烩(5)
  • 原文地址:https://www.cnblogs.com/nightstarsky/p/11459326.html
Copyright © 2020-2023  润新知