Vue源码——使一个函数具有缓存功能

  • 这里的缓存是什么意思?
    • 函数可以缓存一些值
  • 如何使函数具有缓存功能?

思路

  1. 既然要把一个函数转化为有缓存功能的函数,那第一步肯定是创建一个函数,待转换函数作为参数,返回有缓存功能的函数
function cached(fn) {
  return function cachedFn() {
    // ...
  }
}
  1. 既然有缓存功能,那就需要一个 ‘全局变量’ 来保存缓存。这里的全局变量并非我们平时说的全局变量,而是在闭包中的全局变量。补充代码。
function cached(fn) {
  return function cachedFn() {
    var cache = Object.create(null) // 缓存
  }
}

Object.create(proto) ——> 以proto为原型创建一个对象。 当protonull时,创建出来的是一个没有原型的空对象。

空对象.png

对象字面量.png

  1. 缓存函数缓存什么呢? it's up to you。 假设我们要缓存字符串,待缓存函数可以对这个字符串进行一系列的操作。如果缓存中有这个字符串,返回这个字符串,如果没有,往缓存中添加这个字符串并返回。举个例子
function cached(fn) {
  var cache = Object.create(null)
  return function cachedFn(str) {
    var hit = cache[str]
    return hit || (cache[str] = fn(str))

  }
}

// 待缓存函数
function upperStr(str) {
  return str.toUpperCase()
}

// 转换 upperStr 为缓存函数
var cacheUpperStr = cached(upperStr)

// 测试一下
var x = cacheUpperStr('a')
var y = cacheUpperStr('a')

// 打印cache
{
  a: 'A'
}

思考: 为什么要缓存?

  • 当我们对一个数据进行了处理之后, 如果以后经常需要用这个数据,放在缓存中可以避免再次进行处理,而不需要再次处理。
    有人会问:那我不如把这个数据放在一个全局变量里面保存起来
    我的回答是: 当代码量多时,我们应该尽量避免全局变量,或者说,我们要尽可能少去污染全局变量池

扩展

  • 将缓存函数通用化
function cached(fn) {
  var cache = Object.create(null)
  return function cachedFn() {
    var hit = cache[arguments[0]]
    return hit || (cache[arguments[0]] = fn.call(this, ...arguments))
  }
}

弊端: 待缓存函数的参数第一位是缓存中对应的key

你可能感兴趣的:(Vue源码——使一个函数具有缓存功能)