• Vue源码cached解析


    创建一个纯函数的缓存版本

    主要用途:优化性能——对于之前运算过一次的内容,利用闭包原理,缓存起来,避免重复调用,造成性能的浪费

      /**
       * Create a cached version of a pure function.
       */
      function cached (fn) {
        var cache = Object.create(null);
        return (function cachedFn (str) {
          var hit = cache[str];
          return hit || (cache[str] = fn(str))
        })
      }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    这一段的源码很短,但是在源码中使用了19处!这就显得这个函数很重要了

    请添加图片描述

    参数解释

    传入参数

    • fn:(函数类型)

    用于执行需要缓存的方法

    • str:字符串类型

    传入函数fn中的参数

    返回参数

    • 类型为:函数类型

    源码解释

    首先通过Object.create创建一个干净的空对象出来

    然后直接返回一个函数(cachedFn

    函数内首先定义变量,通过传入的参数str去访问创建出来的cache对象

    • 若hit击中了目标,即不为undefined——直接返回,不再调用函数
    • 若未击中,则访问传入的fn函数,并把函数返回值赋值给cache对象

    实验解释

    这样可能比较抽象,我们直接做一个实验,同样直接在浏览器中做

    这一次,我们直接在浏览器的源代码中做——debug

    function cached(fn) {
        var cache = Object.create(null)
        return(
            function cachedFn(str) {
                var hit = cache[str];
                return hit || (cache[str] = fn(str));
            }
        )
    }
    
    var capitalize = cached(function(str) {
        return str.charAt(0).toUpperCase() + str.slice(1);
    })
    
    console.log(capitalize("abc"),"第一次访问")
    console.log(capitalize("abc"),"第二次访问")
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

    直接打一个断点,看看会发生什么

    请添加图片描述

    执行第一次

    在第一次运行时,发现cache是一个空的object,然后直接进入了立即执行函数cacheFn

    这里立即执行函数的作用就是

    • 创建新的作用域,隔离变量——于将var使用变为let效果一致

    str值为abc,也就是传入参数fn中的参数

    下一步执行,当然就是执行fn函数了

    请添加图片描述

    我们可以看到这里的fn函数就是对应capitalize中的function,将str的参数传进来

    执行的结果就是Abc

    右边执行完成后,赋值给左侧的cache[str]

    这里的代码可以翻译成,或许更好理解

    cache[str] = "Abc"
    
    • 1

    也就是说,这里相当于通过方括号属性访问器,创建了一个不存在的属性abc,对应的值是fn返回的Abc

    请添加图片描述

    在右侧监视的cache也明显的多出了一个属性abc

    执行第二次

    此时我们看见,cache此时是具有属性abc的,因此hit的值不再是undefined

    请添加图片描述

    第二次时,很明显的我们可以看见执行过程,没有再次调用fn函数,也就是说没有调用capitalize中的函数,而是直接获取的缓存。

    从而也就做到了对性能的优化。

    源码疑问

    为什么cache是有效的,每次调用函数的时候不都创建了新的吗?

    这里其实使用的是闭包的特性

    在调用cached函数时,会在当前函数创建一个cache对象

    也就是说,其实cache对象是属于当前示例中的capitalize

    这个我们可以直接在属性中看出来

    我们重新debug一次,这一次关注capitalize中的值

    第一次执行时

    请添加图片描述

    第二次执行时

    在运行完cache[str] = fn(str)后,发现的确这里的值增加了一个

    请添加图片描述

    因此,我们可以得出结论。

    小结:

    • 在每一次调用cached时,由于闭包函数的特性,使得cached中的变量值不会被清空,而且这个值是在对应的处理方法中的

    • 因为cache对象是在内部创建的,所以每次调用cached都将是不同的object

      各自拥有独立的缓存空间,而不是全局共用一个

  • 相关阅读:
    Java核心知识体系8:Java如何保证线程安全性
    Ubuntu kill信号-9和-15
    详解【计算机类&面试真题】军队文职考试——第10期:存储系统有哪三种?如何清理内存垃圾?xp系统文件的共享方法 | C#中委托和事件的区别 | 为何备份的时候找不到ghost.txt文件?子网掩码计算
    react面试题详解
    Java日志框架Log4j 2详解
    湖南湘潭家具3D轮廓扫描测量家居三维数字化外观逆向设计-CASAIM中科广电
    java-php-python-客户台账管理计算机毕业设计
    爬虫项目(九):实时抓取csdn热榜数据
    使用Signposts分析App性能
    H3C交换机配置DHCP option43
  • 原文地址:https://blog.csdn.net/qq_22841387/article/details/126289334