返回
前端小白也能秒懂闭包!
前端
2023-10-04 07:36:27
闭包的前世今生
想象一下,你有一个朋友叫 Alice,她是一个资深的前端开发者。有一天,她兴冲冲地跑来跟你说:“嘿,我发现了一个神奇的东西,叫闭包!”
你一脸懵逼:“闭包?那是啥?”
Alice 耐心解释道:“闭包就是一种 JavaScript 函数,它可以访问其创建时的所有变量,即使这些变量已经超出了它的作用域。”
你挠了挠头:“这有什么特别的?”
Alice 笑道:“别急,听我讲个故事。”
小明和闭包的奇遇
小明是一个 JavaScript 新手,他正在编写一个函数来计算购物车的总金额。
function calculateTotal(cart) {
let total = 0;
for (let item of cart) {
total += item.price;
}
return total;
}
乍一看,这个函数似乎没什么问题。但是,小明遇到了一个棘手的情况:当他调用 calculateTotal()
函数时,返回的总金额总是 0。
小明百思不得其解,他仔细检查了代码,发现问题出在 total
变量上。虽然 total
是在函数内部声明的,但它是一个局部变量,只在函数执行期间存在。当函数执行完毕,total
变量也会被销毁。
console.log(total); // 报错:ReferenceError: total is not defined
小明意识到,如果他想在函数外访问 total
变量,就必须想办法让它“活”下来。
这时,小明想起了闭包。他将 calculateTotal()
函数改写成了一个闭包:
const calculateTotal = (cart) => {
let total = 0;
for (let item of cart) {
total += item.price;
}
return () => {
return total;
};
};
这个闭包函数返回了一个匿名函数,这个匿名函数可以访问 total
变量,即使它已经超出了 calculateTotal()
函数的作用域。
现在,小明可以随时调用这个匿名函数来获取购物车的总金额:
const getTotal = calculateTotal([
{ price: 10 },
{ price: 20 },
{ price: 30 },
]);
console.log(getTotal()); // 60
闭包的应用场景
闭包的应用场景非常广泛,这里列举几个常见的例子:
- 状态管理: 闭包可以用来存储和管理组件或应用程序的状态。
- 事件监听器: 闭包可以用来创建事件监听器,即使事件源已被销毁。
- 缓存: 闭包可以用来创建缓存函数,以避免重复计算。
- 私有变量: 闭包可以用来创建私有变量,从而隐藏实现细节。
总结
闭包是一种强大的 JavaScript 特性,它允许函数访问其创建时的所有变量。虽然闭包有时会带来复杂性,但它在许多场景中提供了强大的功能。对于前端小白来说,理解闭包的原理至关重要,这将有助于他们编写更健壮、更灵活的代码。