JS函数缓存

发布时间:2019-05-05

今天看了下vue的源码,看到了一段缓存函数cached,并对其分析探究。

vue里的cached函数源码:

function cached(fn) {
  // 创建一个空对象cache使用key,value对函数结果进行储存    
  var cache = Object.create(null);
  return function cachedFn(str) {
    var hit = cache[str];
    // 如果有此函数fn(str)的储存则直接返回结果,没有则缓存到cache对象里
    return hit || (cache[str] = fn(str));
  };
}

上面vue的这段代码只能存储的函数参数为1个的情况,如果参数大于1个则无效~

// 只有一个参数a可行
var toUpperCase = cached(function(a) {
  return a.toUpperCase();
});
// 有两个参数a,b不行
var sum = cached(function(a,b) {
  return a+b;
});

改造兼容多个参数的cached:

function cached2(fn) {
  var cache = Object.create(null);
  return function() {
    var args = Array.prototype.slice.call(arguments);
    if (args.length < 1) {
      throw new Error("no arguments");
    } else {
      //通过拼接参数形成一个独一无二的键值对key 
      var str = args.join("-");
      // 当有缓存的时候直接取缓存的,没缓存则只需执行fn函数进行处理并缓存
      return cache[str] || (cache[str] = fn.apply(fn, arguments));
    }
  };
}

测试:

var sum = cached2(function(a, b) {
  return a + b;
});

var toUpperCase2 = cached2(function(a) {
  return a.toUpperCase();
});

console.log("sum-----");
console.log(sum(1, 2)); //3
console.log(sum(1, 9)); //10
console.log(sum(1, 2)); //3

console.log(toUpperCase2("aa")); //AA
console.log(toUpperCase2("bb")); //BB
console.log(toUpperCase2("aa")); //AA

总结:

通过闭包,使用key,value键值对形式储存函数的执行结果,避免函数的重复运算。