一.设计思路
1.思考:
创建一个记忆函数,考虑到利用闭包完成,每次函数执行完毕后应该缓存当次函数的传入参数以及执行结果。所以我在在设计函数内部的时候,使用map来完成函数的映射(map可以用function作为key),还考虑到相同函数可能,可能存在传入参入不同的调用,这就意味着map的value不能单一的,必须可以存储多个调用的映射,所以map中value考虑使用数组来存储调用详情,思考完毕,完善代码:
function memoizeFunction(fn) {
let targetMap = new Map()
return function() {
let args = Array.from(arguments)
// 设置目标返回为null
let targetItem = null
// 如果目标函数已经存在
if (targetMap.has(fn)) {
let target = targetMap.get(fn).get('target')
// 查找目标函数:是否存在参数完全相等的调用
targetItem = target.find(item => {
let flag = true
// 如果参数长度相等
if (item.args.length === args.length) {
// 判断参数是否全等
args.find((arg, index) => {
if (arg !== item.args[index]) {
flag = false
return false
}
})
}else {
flag = false
}
return flag
})
// 如果目标函数不存在
if(!targetItem){
// 创建目标函数
targetItem = {
args: args,
val: fn(...arguments),
callTimes:target.length+1
}
// 将目标函数添加到目标函数数组中
target.push(targetItem)
}
}else {
// 如果目标函数不存在
let map = new Map()
// 创建目标函数
targetItem = {
// 参数
args: args,
// 返回值
val: fn(...arguments),
// 调用次数
callTimes:1
}
// 将目标函数添加到目标函数数组中
let arr = [targetItem]
// 将目标函数数组添加到目标函数map中
map.set('target',arr)
// 将目标函数map添加到目标函数map中
targetMap.set(fn,map)
}
// 返回目标函数的值
return targetItem.val
}
}
2.实际使用
let test = memoizeFunction((a, b) => {
console.log('执行了')
return a + b
})
console.log(test(1,2))
console.log(test(1,2))
console.log(test(2,2))
console.log(test(2,3))
// 打印输出:
// 执行了
// 3
// 3
// 执行了
// 4
// 执行了
// 5