首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >JS 利用高阶函数实现函数缓存(备忘模式)

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

作者头像
前端下午茶
发布2018-10-22 14:47:33
2.5K0
发布2018-10-22 14:47:33
举报

1. 高阶函数

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

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

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

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,如果是开销很大的操作的话就比较消耗性能了,这里其实可以对这个计算进行一次缓存。

所以这里可以利用高阶函数的思想来实现一个简单的缓存,我可以在函数内部用一个对象存储输入的参数,如果下次再输入相同的参数,那就比较一下对象的属性,把值从这个对象里面取出来。

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

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 1. 高阶函数
  • 2. 高阶函数实现缓存(备忘模式)
相关产品与服务
对象存储
对象存储(Cloud Object Storage,COS)是由腾讯云推出的无目录层次结构、无数据格式限制,可容纳海量数据且支持 HTTP/HTTPS 协议访问的分布式存储服务。腾讯云 COS 的存储桶空间无容量上限,无需分区管理,适用于 CDN 数据分发、数据万象处理或大数据计算与分析的数据湖等多种场景。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档