【前端学习——js篇】7.函数缓存

具体见:https://github.com/febobo/web-interview

7.函数缓存

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

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

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

其实现主要通过闭包、柯里化和高阶函数。

下面主要介绍下柯里化:

①柯里化

柯里化(currying)是一种函数式编程的概念,指的是将一个带有多个参数的函数转换成一系列只接受一个参数的函数的过程。这些接受单一函数的函数可以依次调用,每次调用都会返回一个新的函数,直到所有参数收集完毕,最好返回最终的结果。


具体例子

js 复制代码
//柯里化
// 原始的加法函数
function add(x, y) {
    return x + y;
}

// 柯里化后的加法函数
function curriedAdd(x) {
    return function(y) {
        return x + y;
    };
}

// 使用柯里化后的函数
const add5 = curriedAdd(5);
console.log(add5(3)); // 输出: 8

const add7 = curriedAdd(7);
console.log(add7(3)); // 输出: 10

在上面的示例中,add 是一个接受两个参数的加法函数。通过柯里化,我们定义了一个 curriedAdd 函数,它接受一个参数 x,并返回一个函数,这个返回的函数接受参数 y,并返回 x + y 的结果。通过这种方式,我们可以先传递一个参数 x,然后再传递另一个参数 y,实现了对多参数函数的拆分调用。

通过柯里化,我们可以将一个接受多个参数的函数转换为一个接受单个参数的函数链。这种技术有助于简化函数的调用方式,提高函数的灵活性和复用性。

②高阶函数

高阶函数(Higher-Order Functions)是指接受一个或多个函数作为参数,返回一个函数的函数。换句话说,高阶函数要么接受一个或多个函数作为参数,要么返回一个函数,或者同时具备这两个特点。

在js 中,函数被视为一等公民,因此可以像其他值一样被传递和操作。这种特性使得函数可以作为参数传递给其他函数,也可以作为其他函数的返回值。


具体例子

js 复制代码
// 高阶函数示例:接受一个函数作为参数
function operate(func, x, y) {
    return func(x, y);
}

function add(a, b) {
    return a + b;
}

function multiply(a, b) {
    return a * b;
}

console.log(operate(add, 3, 4)); // 输出: 7
console.log(operate(multiply, 3, 4)); // 输出: 12

// 高阶函数示例:返回一个函数
function createMultiplier(multiplier) {
    return function(x) {
        return x * multiplier;
    };
}

const double = createMultiplier(2);
console.log(double(5)); // 输出: 10

在上面的示例中,operate 是一个接受一个函数作为参数的高阶函数,它可以根据传入的函数不同来执行不同的操作。另外,createMultiplier 是一个返回函数的高阶函数,它返回一个乘法函数,用于计算传入值的倍数。

③函数缓存

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


js 复制代码
const memoize = function (func, content) {
    let cache = Object.create(null)
    content = content || this //函数被定义时的上下文
    return (...key) => {
        console.log(cache);
      if (!cache[key]) {
        cache[key] = func.apply(content, key)
      }
      return cache[key]
    }
  }

function add(a,b){
    return a + b;
}

const calc = memoize(add);
const num1 = calc(100,200);
//输出cache可以看到:[Object: null prototype] { '100,200': 300}
const num2 = calc(100,200); //直接从缓存得到结果
const num3 = calc(1000,2000);
console.log(num2); 

过程分析:

  • 在当前函数作用域定义了一个空对象,用于缓存运行结果
  • 运用柯里化返回一个函数,返回的函数因为作用域链的原因,可以访问到cache
  • 然后判断输入参数是不是在cache的中。如果已经存在,直接返回cache的内容,如果没有存在,使用函数func对输入参数求值,然后把结果存储在cache中。
④应用场景

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

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

  • 对于昂贵的函数调用,执行复杂计算的函数
  • 对于具有有限且高度重复输入范围的函数
  • 对于具有重复输入值的递归函数
  • 对于纯函数,即每次使用特定输入调用时返回相同输出的函数
相关推荐
weixin_455446179 分钟前
Python学习的主要知识框架
开发语言·python·学习
她似晚风般温柔7891 小时前
Uniapp + Vue3 + Vite +Uview + Pinia 分商家实现购物车功能(最新附源码保姆级)
开发语言·javascript·uni-app
Jiaberrr2 小时前
前端实战:使用JS和Canvas实现运算图形验证码(uniapp、微信小程序同样可用)
前端·javascript·vue.js·微信小程序·uni-app
everyStudy3 小时前
JS中判断字符串中是否包含指定字符
开发语言·前端·javascript
城南云小白3 小时前
web基础+http协议+httpd详细配置
前端·网络协议·http
前端小趴菜、3 小时前
Web Worker 简单使用
前端
web_learning_3213 小时前
信息收集常用指令
前端·搜索引擎
Ylucius3 小时前
动态语言? 静态语言? ------区别何在?java,js,c,c++,python分给是静态or动态语言?
java·c语言·javascript·c++·python·学习
tabzzz3 小时前
Webpack 概念速通:从入门到掌握构建工具的精髓
前端·webpack
LvManBa3 小时前
Vue学习记录之六(组件实战及BEM框架了解)
vue.js·学习·rust