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))
    })
  }

这一段的源码很短,但是在源码中使用了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"),"第二次访问")

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

执行第一次

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

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

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

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

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

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

执行的结果就是Abc

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

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

cache[str] = "Abc"

也就是说,这里相当于通过方括号属性访问器,创建了一个不存在的属性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

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

到此这篇关于Vue源码cached解析的文章就介绍到这了,更多相关Vue cached内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • Vue编译器解析compile源码解析

    目录 引言 解析 compile compile 源码 配置选项 属性分别解析 finalOptions添加warn 方法 两个特殊的属性处理 引言 在上篇文章 Vue编译器源码分析compileToFunctions作用中我们介绍到了,在 compileToFunctions 方法中: // compile var compiled = compile(template, options); 而真正的编译工作是依托于 compile 函数,接下来我们详细解析 compile . 解析 comp

  • vue parseHTML 函数源码解析

    目录 正文 函数开头定义的一些常量和变量 while 循环 textEnd ===0 parseStartTag 函数解析开始标签 总结: 正文 接上篇: Vue编译器源码分析AST 抽象语法树 function parseHTML(html, options) { var stack = []; var expectHTML = options.expectHTML; var isUnaryTag$$1 = options.isUnaryTag || no; var canBeLeftOpen

  • Vue编译器源码分析compileToFunctions作用详解

    目录 引言 Vue.prototype.$mount函数体 源码出处 options.delimiters & options.comments compileToFunctions函数逐行分析 createFunction 函数源码 引言 Vue编译器源码分析 接上篇文章我们来分析:compileToFunctions的作用. 经过前面的讲解,我们已经知道了 compileToFunctions 的真正来源你可能会问为什么要弄的这么复杂?为了搞清楚这个问题,我们还需要继续接触完整的代码. 下面

  • Vue源码makeMap函数深入分析

    目录 前言 参数解释 源码解释 源码疑问 为什么使用[ ]访问属性 前言 创建一个map,返回一个检查key是否在map中的函数 主要用途: 判断标签是原生组件还是自定义组件,直接通过map这种key-value一一对应的数据结构,实现快速判断 /** * Make a map and return a function for checking if a key * is in that map. */ function makeMap ( str, expectsLowerCase ) {

  • Vue编译器optimize源码分析

    目录 引言 optimize 源码之旅 markStatic$1源码 isStatic源码 复杂点的 回归到markStatic$1 markStaticRoots 源码 引言 接上文 parseHTML 函数源码解析 chars.end.comment钩子函数 上一章节我们讲到通过解析将template转成AST(抽象语法树),接下来继续对模型树优化,进行静态标注.那么问题来了,什么是静态标注?为什么要静态标注. 在源码的注释中我们找到了下面这段话: /** * Goal of the opt

  • Vue源码cached解析

    目录 前言 参数解释 传入参数 返回参数 源码解释 实验解释 源码疑问 前言 创建一个纯函数的缓存版本 主要用途:优化性能——对于之前运算过一次的内容,利用闭包原理,缓存起来,避免重复调用,造成性能的浪费 /** * Create a cached version of a pure function. */ function cached (fn) { var cache = Object.create(null); return (function cachedFn (str) { var

  • 深入解析vue 源码目录及构建过程分析

    ​" 本文主要梳理一下vue代码的目录,以及vue代码构建流程,旨在对vue源码整体有一个认知,有助于后续对源码的阅读." 一.目录结构 上图是对vue的代码的所有目录进行的梳理,其中源码位于src目录下,下面对src下的目录进行介绍. compiler 该目录是编译相关的代码,即将 template 模板转化成 render 函数的代码. vue 提供了 render 函数,render 函数作用是用来创建 VNode,但在平时开发中,绝大多数情况下使用 template 来创建 H

  • Vue源码解析之Template转化为AST的实现方法

    什么是AST 在Vue的mount过程中,template会被编译成AST语法树,AST是指抽象语法树(abstract syntax tree或者缩写为AST),或者语法树(syntax tree),是源代码的抽象语法结构的树状表现形式. Virtual Dom Vue的一个厉害之处就是利用Virtual DOM模拟DOM对象树来优化DOM操作的一种技术或思路. Vue源码中虚拟DOM构建经历 template编译成AST语法树 -> 再转换为render函数 最终返回一个VNode(VNod

  • 深入解析Vue源码实例挂载与编译流程实现思路详解

    在正文开始之前,先了解vue基于源码构建的两个版本,一个是 runtime only ,另一个是 runtime加compiler 的版本,两个版本的主要区别在于后者的源码包括了一个编译器. 什么是编译器,百度百科上面的解释是 简单讲,编译器就是将"一种语言(通常为高级语言)"翻译为"另一种语言(通常为低级语言)"的程序.一个现代编译器的主要工作流程:源代码 (source code) → 预处理器 (preprocessor) → 编译器 (compiler) →

  • vue 源码解析之虚拟Dom-render

    vue 源码解析 --虚拟Dom-render instance/index.js function Vue (options) { if (process.env.NODE_ENV !== 'production' && !(this instanceof Vue) ) { warn('Vue is a constructor and should be called with the `new` keyword') } this._init(options) } renderMixin

  • Vue源码解析之数组变异的实现

    力有不逮的对象 众所周知,在 Vue 中,直接修改对象属性的值无法触发响应式.当你直接修改了对象属性的值,你会发现,只有数据改了,但是页面内容并没有改变. 这是什么原因? 原因在于: Vue 的响应式系统是基于Object.defineProperty这个方法的,该方法可以监听对象中某个元素的获取或修改,经过了该方法处理的数据,我们称其为响应式数据.但是,该方法有一个很大的缺点,新增属性或者删除属性不会触发监听,举个栗子: var vm = new Vue({ data () { return

  • 从vue源码解析Vue.set()和this.$set()

    前言 最近死磕了一段时间vue源码,想想觉得还是要输出点东西,我们先来从Vue提供的Vue.set()和this.$set()这两个api看看它内部是怎么实现的. Vue.set()和this.$set()应用的场景 平时做项目的时候难免不会对 数组或者对象 进行这样的骚操作操作,结果发现,咦~~,他喵的,怎么页面没有重新渲染. const vueInstance = new Vue({ data: { arr: [1, 2], obj1: { a: 3 } } }); vueInstance.

  • vue源码之批量异步更新策略的深入解析

    vue异步更新源码中会有涉及事件循环.宏任务.微任务的概念,所以先了解一下这几个概念. 一.事件循环.宏任务.微任务 1.事件循环Event Loop:浏览器为了协调事件处理.脚本执行.网络请求和渲染等任务而定制的工作机制. 2.宏任务Task: 代表一个个离散的.独立的工作单位.浏览器完成一个宏任务,在下一个宏任务开始执行之前,会对页面重新渲染.主要包括创建文档对象.解析HTML.执行主线JS代码以及各种事件如页面加载.输入.网络事件和定时器等. 3.微任务:微任务是更小的任务,是在当前宏任务

  • vue Proxy数据代理进行校验部分源码实例解析

    目录 initProxy 触发代理 数据过滤 总结 initProxy 数据拦截的思想除了为构建响应式系统准备,它也可以为数据进行筛选过滤,我们接着往下看初始化的代码,在合并选项后,vue接下来会为vm实例设置一层代理,这层代理可以为vue在模板渲染时进行一层数据筛选 Vue.prototype._init = function(options) { // 选项合并 ... { // 对vm实例进行一层代理 initProxy(vm); } ... } initProxy // 代理函数 var

  • Vue 源码分析之 Observer实现过程

    导语: 本文是对 Vue 官方文档深入响应式原理(https://cn.vuejs.org/v2/guide/reactivity.html)的理解,并通过源码还原实现过程. 响应式原理可分为两步,依赖收集的过程与触发-重新渲染的过程.依赖收集的过程,有三个很重要的类,分别是 Watcher.Dep.Observer.本文主要解读 Observer . 这篇文章讲解上篇文章没有覆盖到的 Observer 部分的内容,还是先看官网这张图: Observer 最主要的作用就是实现了上图中touch

随机推荐