JavaScript中如何实现函数缓存?有哪些应用场景?

65 篇文章 2 订阅

一、是什么

函数缓存,就是将函数运算过的结果进行缓存

本质上就是用空间(缓存存储)换时间(计算过程)

常用于缓存数据计算结果和缓存对象.

const add = (a,b) => a+b;
const calc = memoize(add); // 函数缓存
calc(10,20);// 30
calc(10,20);// 30 缓存

二、如何实现

实现函数缓存主要依靠闭包、柯里化、高阶函数,这里再简单复习下:

闭包

闭包可以理解成,函数 + 函数体内可访问的变量总和

(function() {
    var a = 1;
    function add() {
        const b = 2
        let sum = b + a
        console.log(sum); // 3
    }
    add()
})()

 

add函数本身,以及其内部可访问的变量,即 a = 1,这两个组合在⼀起就形成了闭包

柯里化

把接受多个参数的函数转换成接受一个单一参数的函数.

// 非函数柯里化
var add = function (x,y) {
    return x+y;
}
add(3,4) //7

// 函数柯里化
var add2 = function (x) {
    //**返回函数**
    return function (y) {
        return x+y;
    }
}
add2(3)(4) //7

将一个二元函数拆分成两个一元函数

高阶函数

通过接收其他函数作为参数或返回其他函数的函数

function foo(){
  var a = 2;

  function bar() {
    console.log(a);
  }
  return bar;
}
var baz = foo();
baz();//2

 

函数 foo 如何返回另一个函数 barbaz 现在持有对 foo 中定义的bar 函数的引用。由于闭包特性,a的值能够得到

下面再看看如何实现函数缓存,实现原理也很简单,把参数和对应的结果数据存在一个对象中,调用时判断参数对应的数据是否存在,存在就返回对应的结果数据,否则就返回计算结果

如下所示

const memoize = function (func, content) {
  let cache = Object.create(null)
  content = content || this
  return (...key) => {
    if (!cache[key]) {
      cache[key] = func.apply(content, key)
    }
    return cache[key]
  }
}

调用方式也很简单

const calc = memoize(add);
const num1 = calc(100,200)
const num2 = calc(100,200) // 缓存得到的结果 

过程分析:

  • 在当前函数作用域定义了一个空对象,用于缓存运行结果

  • 运用柯里化返回一个函数,返回的函数由于闭包特性,可以访问到cache

  • 然后判断输入参数是不是在cache的中。如果已经存在,直接返回cache的内容,如果没有存在,使用函数func对输入参数求值,然后把结果存储在cache

三、应用场景

虽然使用缓存效率是非常高的,但并不是所有场景都适用,因此千万不要极端的将所有函数都添加缓存

以下几种情况下,适合使用缓存:

  • 对于昂贵的函数调用,执行复杂计算的函数

  • 对于具有有限且高度重复输入范围的函数

  • 对于具有重复输入值的递归函数

  • 对于纯函数,即每次使用特定输入调用时返回相同输出的函数

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
闭包在编程有很多应用场景,以下是一些常见的例子: 1. 数据封装和私有变量:闭包可以用来创建私有变量,从而实现数据封装和保护。这在模块化编程和面向对象编程非常有用。 2. 函数工厂:闭包可以用来创建一系列相关的函数,这些函数共享相同的外部变量。这在创建类似于Python的装饰器或JavaScript的高阶函数时非常有用。 3. 延迟执行和计时器:闭包可以用来实现延迟执行和定时器功能。例如,在JavaScript,setTimeout和setInterval函数使用闭包来实现延迟执行和定时器功能。 4. 记忆化(Memoization):闭包可以用来实现记忆化,即缓存函数的计算结果,以便在后续调用重用。这可以提高函数的性能,特别是在处理计算密集型任务时。 5. 事件处理和回调函数:在JavaScript等事件驱动的编程环境,闭包常用于实现事件处理和回调函数。闭包可以捕获事件处理函数的上下文,使得事件处理函数可以访问其所需的外部变量。 6. 部分应用(Partial Application)和柯化(Currying):闭包可以用来实现部分应用和柯化,这是一种将多参数函数转换为一系列单参数函数的技术。这可以简化函数调用,使得代码更加简洁和可读。 7. 实现迭代器和生成器:在某些编程语言,例如Python和JavaScript,闭包可以用来实现迭代器和生成器,这是一种用于遍历数据结构的高效方法
最新发布
07-14

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值