JS 利用高阶函数实现函数缓存(备忘模式)

1. 高阶函数

高阶函数就是那种输入参数里面有一个或者多个函数,输出也是函数的函数,这个在js里面主要是利用闭包实现的,最简单的就是常常看到的在一个函数内部输出另外一个函数,好比前端

var test = function() {
    return function() {}
}

这个主要是利用闭包来保持着做用域:segmentfault

var add = function() {
    var num = 0;
    return function(a) {
        return num = num + a;
    }
}
add()(1);      // 1
add()(2);      // 2

这里的两个add()(1)和add()(2)不会互相影响,能够理解为每次运行add函数后返回的都是不一样的匿名函数,就是每次add运行后return的function其实都是不一样的,因此运行结果也是不会影响的。数组

若是换一种写法,好比:缓存

var add = function() {
    var num = 0;
    return function(a) {
        return num = num + a;
    }
}
var adder = add();
adder(1); // 1
adder(2); // 3

这样的话就会在以前运算结果基础上继续运算,意思就是这两个 adder 运行的时候都是调用的同一个 num微信

2. 高阶函数实现缓存(备忘模式)

好比有个函数:闭包

var add = function(a) {
    return a + 1;
}

每次运行add(1)的时候都会输出2,可是输入1每次仍是会计算一下1+1,若是是开销很大的操做的话就比较消耗性能了,这里其实能够对这个计算进行一次缓存。
因此这里能够利用高阶函数的思想来实现一个简单的缓存,我能够在函数内部用一个对象存储输入的参数,若是下次再输入相同的参数,那就比较一下对象的属性,把值从这个对象里面取出来。app

const memorize = function(fn) {
  const cache = {}
  return function(...args) {
    const _args = JSON.stringify(args)
    return cache[_args] || (cache[_args] = fn.apply(fn, args))
  }
}
const add = function(a) {
  return a + 1
}
const adder = memorize(add)
adder(1)    // 2    cache: { '[1]': 2 }
adder(1)    // 2    cache: { '[1]': 2 }
adder(2)    // 3    cache: { '[1]': 2, '[2]': 3 }

JSON.stringify把传给 adder 函数的参数变成了字符串,而且把它当作 cache 的 key,将 add 函数运行的结果当作 value 传到了 cache 里面,这样 memorize 的匿名函数运行的时候会返回cache[_args],若是cache[_args]不存在的话就返回fn.apply(fn,args),把fn.apply(fn, arguments)赋值给cache[_args]并返回。
注意:cache不能够是Map,由于Map的键是使用===比较的,[1]!==[1],所以即便传入相同的对象或者数组,那么仍是被存为不一样的键。函数

const memorize = function(fn) {        //  X 错误示范
  const cache = new Map()
  return function(...args) {
    return cache.get(args) || cache.set(args, fn.apply(fn, args)).get(args)
  }
}
const add = function(a) {
  return a + 1
}
const adder = memorize(add)
adder(1)    // 2    cache: { [ 1 ] => 2 }
adder(1)    // 2    cache: { [ 1 ] => 2, [ 1 ] => 2 }
adder(2)    // 3    cache: { [ 1 ] => 2, [ 1 ] => 2, [ 2 ] => 3 }

本文是系列文章,能够相互参考印证,共同进步~性能

  1. JS 抽象工厂模式
  2. JS 工厂模式
  3. JS 建造者模式
  4. JS 原型模式
  5. JS 单例模式
  6. JS 回调模式
  7. JS 外观模式
  8. JS 适配器模式
  9. JS 利用高阶函数实现函数缓存(备忘模式)
  10. JS 状态模式
  11. JS 桥接模式
  12. JS 观察者模式

网上的帖子大多深浅不一,甚至有些先后矛盾,在下的文章都是学习过程当中的总结,若是发现错误,欢迎留言指出~学习

参考: <JavaScript模式>P78

PS:欢迎你们关注个人公众号【前端下午茶】,一块儿加油吧~

另外能够加入「前端下午茶交流群」微信群,长按识别下面二维码便可加我好友,备注加群,我拉你入群~

相关文章
相关标签/搜索