这里的缓存是什么意思?
函数可以缓存一些值
如何使函数具有缓存功能?
思路
既然要把一个函数转化为有缓存功能的函数, 那第一步肯定是创建一个函数, 待转换函数作为参数, 返回有缓存功能的函数
- function cached(fn) {
- return function cachedFn() {
- // ...
- }
- }
既然有缓存功能, 那就需要一个 '全局变量' 来保存缓存. 这里的全局变量并非我们平时说的全局变量, 而是在闭包中的全局变量. 补充代码.
- function cached(fn) {
- return function cachedFn() {
- var cache = Object.create(null) // 缓存
- }
- }
Object.create(proto) --> 以 proto 为原型创建一个对象. 当 proto 为 null 时, 创建出来的是一个没有原型的空对象.
空对象. PNG
对象字面量. PNG
缓存函数缓存什么呢? it's up to you. 假设我们要缓存字符串, 待缓存函数可以对这个字符串进行一系列的操作. 如果缓存中有这个字符串, 返回这个字符串, 如果没有, 往缓存中添加这个字符串并返回. 举个例子
- function cached(fn) {
- var cache = Object.create(null)
- return function cachedFn(str) {
- var hit = cache[str]
- return hit || (cache[str] = fn(str))
- }
- }
- // 待缓存函数
- function upperStr(str) {
- return str.toUpperCase()
- }
- // 转换 upperStr 为缓存函数
- var cacheUpperStr = cached(upperStr)
- // 测试一下
- var x = cacheUpperStr('a')
- var y = cacheUpperStr('a')
- // 打印 cache
- {
- a: 'A'
- }
思考: 为什么要缓存?
当我们对一个数据进行了处理之后, 如果以后经常需要用这个数据, 放在缓存中可以避免再次进行处理, 而不需要再次处理.
有人会问: 那我不如把这个数据放在一个全局变量里面保存起来
我的回答是: 当代码量多时, 我们应该尽量避免全局变量, 或者说, 我们要尽可能少去污染全局变量池
扩展
将缓存函数通用化
- function cached(fn) {
- var cache = Object.create(null)
- return function cachedFn() {
- var hit = cache[arguments[0]]
- return hit || (cache[arguments[0]] = fn.call(this, ...arguments))
- }
- }
弊端: 待缓存函数的参数第一位是缓存中对应的 key
来源: http://www.jianshu.com/p/4fee2bae7db4