闭包的作用之一就是可以通过闭包,把函数执行完后的本应被清理的变量保存下来,则可以通过闭包来实现缓存
通过闭包实现缓存(含有解析)
function memorize(fn) {
var cache = {} //创建一个缓存变量,由于memorize的子函数(return的函数)中使用了闭包,所有擦车变量并不会每次执行memorize都会被重置成空变量,而是会缓存起来
return function() {
var args = Array.prototype.slice.call(arguments) //这里的arguments是adder(1)中的参数1,而不是fn,因为调用这里的是adder(1)。此行是把arguments的类数组变成数组。
var key = JSON.stringify(args) //这里把args中的数据变成字符串格式,因为key是用来当cache对象的键值的,必须是字符串格式
return cache[key] || (cache[key] = fn.apply(fn, args))
//如果cache中有结果,就直接返回结果;如果没有的话,则执行(cache[key] = fn.apply(fn, args)),这里有两步操作,首先执行=右边的fn.apply(fn, args)),
//并且由于下一步操作不涉及运算,所以这个值就是return的返回值,第二步是把fn.apply(fn, args))的值存给key
//这里fn.apply(fn, args)和fn(args[0])一样的结果
}
}
function add(a) {
return a + 1
}
var adder = memorize(add)
adder(1) // 输出: 2 当前: cache: { '[1]': 2 }
adder(1) // 输出: 2 当前: cache: { '[1]': 2 }
adder(2) // 输出: 3 当前: cache: { '[1]': 2, '[2]': 3 }