4 个有用的 JavaScript 闭包技巧

什么是闭包?

根据 MDN:“闭包是捆绑在一起(封闭)的函数及其周围状态(词法环境)的引用的组合。换句话说,闭包使您可以从内部函数访问外部函数的作用域。在 JavaScript 中,每次创建函数时都会创建闭包。”

例如
const getShowName = () => {
const name = “fatfish” // name is a local variable created by getShowName

return () => {
console.log(name) // use variable declared in the parent function
}
}
const showName = getShowName()
showName() // fatfish
作为前端开发工程师,我们在很多场景中都会用到它,它的功能确实很强大。

1. 解决循环中的问题
for (var i = 0; i < 3; i++) {
setTimeout(() => {
console.log(i) // What will i print out?
}, 1000 * i)
}
我们怎样才能让它打印0、1、2呢?

是的,你可以使用闭包来解决这个问题。它很快就会打印出 0、1 和 2。

for (var i = 0; i < 3; i++) {
((n) => {
setTimeout(() => {
console.log(n) // What will i print out?
}, 1000 * n)
})(i)
}
当然,我们还有另一种更简单的方法,只需将var替换为let即可解决这个问题。

for (let i = 0; i < 3; i++) {
setTimeout(() => {
console.log(i) // What will i print out?
}, 1000 * i)
}

2.记忆功能
利用闭包的特性,我们可以减少计算量,提高我们编写的程序的性能。
const memoize = (callback) => {
const cache = new Map()
return function (n) {
if (cache.has(n)) { // When it already exists in the cache, the result will be returned directly, we don’t need to calculate it again
return cache.get(n)
} else {
const res = callback.call(this, n)
cache.set(n, res) // After the first calculation, the result will be cached
return res
}
}
}
const fibonacci = memoize(function fib (n) {
if (n === 1) {
return 1
}
if (n === 2 || n === 3) {
return 2
}
return fib(n - 1) + fib(n - 2)
})
console.log(fibonacci(1)) // 1
console.log(fibonacci(10)) // 68
console.log(fibonacci(10)) // 68 Read from cache instead of computing again

3. 封装私有变量和属性
很早以前,我们经常通过闭包来实现对私有变量的保护。
我们只能通过getName和setName来获取和设置_name的值。
这样我们就可以有效防止_name被恶意修改。
const createName = (name) => {
let _name = name

return {
getName () {
return _name
},
setName (name) {
_name = name
}
}
}
const p = createName(‘fatfish’)
p.getName() // fatfish
p.setName(‘medium’)
p.getName() // medium

4.函数柯里化
作为一名前端开发工程师,我相信你已经了解了什么是函数柯里化。让我们尝试使用闭包来实现它。

const curry = (callback, …args) => {
return function (…innerArgs) {
innerArgs = args.concat(innerArgs)

if (innerArgs.length >= callback.length) {
  return callback.apply(this, innerArgs)
} else {
  return curry(callback, innerArgs)
}

}
}

const add = curry((a, b, c) => {
return a + b + c
}, 1)
console.log(add(2, 3)) // 6

4种关于的闭包的技巧我们说完了, 你还知道其他的什么方法吗?

猜你喜欢

转载自blog.csdn.net/longxiaobao123/article/details/132777862