一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第N天,点击查看活动详情。
什么是函数缓存
函数缓存,就是将函数运算过的结果进行缓存,本质上就是用空间(缓存存储)换时间(计算过程),一般用于缓存数据计算结果和缓存对象
实现函数缓存
实现函数缓存我们主要使用到的有闭包、柯里化、高阶函数
闭包
闭包可以简单理解成内部的函数可以访问外部函数的变量
(function () {
const obj = {
name: '小王'
}
function fn1 () {
console.log(obj.name) // 小王
}
fn1()
})()
(function(){})()这种写法是函数的自调用,我们在fn1里可以访问到fn里的变量,这就是闭包,实现了函数缓存
函数柯里化
把接受多个参数的函数转换成接受一个单一参数的函数
const fn3 = (a, b) => {
return a + b
}
console.log(fn3(1, 2)) // 3
// 函数柯里化
const fn4 = a => {
return function (b) {
return a + b
}
}
console.log(fn4(1)(2)) // 3
将一个二元函数拆分成两个一元函数 高阶函数
通过接收其他函数作为参数或返回其他函数的函数
function First () {
let a = 99
function Second () {
return (a = 88)
}
return Second
}
const num = First()
console.log(num()) // 88
函数 First 返回另一个函数 Second,num 现在持有对 First 中定义的Second 函数的引用。由于闭包特性,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(fn3);
const num1 = calc(100,200)
const num2 = calc(100,200) // 缓存得到的结果
- 在当前函数作用域定义了一个空对象,用于缓存运行结果
- 运用柯里化返回一个函数,返回的函数由于闭包特性,可以访问到
cache - 然后判断输入参数是不是在
cache的中。如果已经存在,直接返回cache的内容,如果没有存在,使用函数func对输入参数求值,然后把结果存储在cache中
三、函数缓存应用场景
虽然使用缓存效率是非常高的,但并不是所有场景都适用,以下几种情况下,适合使用缓存:
- 对于昂贵的函数调用,执行复杂计算的函数
- 对于具有有限且高度重复输入范围的函数
- 对于具有重复输入值的递归函数
- 对于纯函数,即每次使用特定输入调用时返回相同输出的函数