Offer 驾到,掘友接招!我正在参与2022春招打卡活动,点击查看活动详情。
本题难度:⭐ ⭐
答:
闭包的作用是创造私有变量,且延长私有变量的生命周期,这样的特性可以用来做缓存模块,让私有变量当成缓存一直驻扎在内存中,直到页面被销毁。
下面,我用两个例子来列举如何用闭包实现一个缓存模块。
例1 缓存耗时的计算
假设有一个计算非常耗时,需要设计一个缓存模块把计算结果存起来,下次计算前先看一下缓存里有没有值,有值就直接返回,就这样就不用每次重新计算了。
我们用计算素数来模拟一个非常耗时的计算,计算素数的代码如下:
function isPrime (n) {
let res = n > 1
for (let i = 2; i < n; i++) {
if (n % i === 0) {
res = false
break
}
}
return res
}
console.log(isPrime(2)) // true
console.log(isPrime(3)) // true
console.log(isPrime(4)) // false
console.log(isPrime(5)) // true
接下来,用一个 cache 对象来缓存计算结果,如果 cache 中没有值就存进去,cache 中有值就直接返回。
const cache = {}
function isPrime (n) {
if (n in cache) {
console.log(`cache中有${n},直接返回 :>> `, cache[n])
return cache[n]
}
let res = n > 1
for (let i = 2; i < n; i++) {
if (n % i === 0) {
res = false
break
}
}
console.log(`cache中没有${n},存进去 :>> `, res)
cache[n] = res
return res
}
测试一下:
isPrime(3)
isPrime(4)
isPrime(5)
isPrime(5)
isPrime(5)
console.log('cache :>> ', cache)
以上代码虽然可以实现缓存功能,但是最大的问题就是缓存需要定义一个全局变量 cache。
这个时候,闭包出现了,其实这个 cache 变量是可以用闭包隐藏的。
把 cache 定义到一个匿名函数内,在这个匿名函数内部返回计算素数的函数,这样就可以在外部调用计算素数的函数,而且 cache 对象就被藏到了闭包里,全局访问不到 cache 对象,代码如下:
const isPrime = (function () {
const cache = {}
return function (n) {
if (n in cache) {
console.log(`cache中有${n},直接返回 :>> `, cache[n])
return cache[n]
}
let res = n > 1
for (let i = 2; i < n; i++) {
if (n % i === 0) {
res = false
break
}
}
console.log(`cache中没有${n},存进去 :>> `, res)
cache[n] = res
return res
}
})()
isPrime(3)
isPrime(4)
isPrime(5)
isPrime(5)
isPrime(5)
例2 仿 localStorage
实现一个简单的类似于 localStorage 的功能,可以通过 set 方法存值,get 方法取值。
原理和例1一样,都是把 cache 定义到一个匿名函数内部。
这个匿名函数返回一个对象,在对象上有缓存模块的 get 和 set 方法,通过 set 方法把数据存到匿名函数内部的 cache 对象上,通过 get 方法读取数据。
const myStorage = (function () {
const cache = {}
return {
set: (key, val) => {
cache[key] = val
},
get: (key) => {
if (key in cache) {
return cache[key]
}
}
}
})()
myStorage.set('name', 'lin')
myStorage.set('age', 18)
console.log(myStorage.get('name'))
console.log(myStorage.get('age'))
结尾
如果我的文章对你有帮助,你的👍就是对我的最大支持^_^
你也可以关注《前端每日一问》这个专栏,防止失联哦~
我是阿林,输出洞见技术,再会!
上一篇:
下一篇: