解析手写JS之闭包缓存

368 阅读1分钟

闭包的作用之一就是可以通过闭包,把函数执行完后的本应被清理的变量保存下来,则可以通过闭包来实现缓存

通过闭包实现缓存(含有解析)

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 }