前端面试5 分钟说清楚 JavaScript 闭包
一位前端宝妈
什么是闭包?
mdn上说:闭包是由捆绑起来(封闭的)的函数和函数周围状态(词法环境)的引用组合而成。换言之,闭包让函数能访问它的外部作用域。在 JavaScript 中,闭包会随着函数的创建而同时创建。
用一句话简单说明:闭包就是能够读取其他函数内部变量的函数。

闭包的形成条件?
- 函数嵌套
- 内部函数引用外部函数的局部变量
闭包示例:
function fun(){ var count=1; return function(){ console.log(count) }}var fun2 = fun()fun2() // 打印 1fun2() // 打印 1,这也就是闭包的优点:延长外部函数局部变量count的生命周期,也同时是闭包的缺点,容易造成内存泄漏闭包的优点:
- 数据持久化:闭包能让变量的值始终保持在内存中,不会因为函数执行完毕而被销毁,从而延长外部函数局部变量的生命周期。
- 封装性:可以把操作数据的方法封装在一起,提高代码的安全性和可维护性。
闭包的缺点:
由于闭包会使得函数中的变量长期保存在内存中,因此过度使用闭包可能会导致内存消耗过大,甚至造成内存泄露。—— 解决:不用时手动把内层函数设为 null,释放内存。
闭包的应用场景:
- 在基于事件的前端代码中,你定义某种行为,然后将其添加到由用户触发的事件上(比如点击或者按键)。代码添加为回调(在事件响应中执行的一个函数)。
- 用闭包模拟私有方法:创建共享的词法环境(立即执行IIFE函数)或者面向对象编程中(非立即执行函数)数据隐藏和封装。
- 节流防抖函数(下一篇讲)
- 高阶函数(下一篇讲)
- 函数柯里化(下一篇讲)
经典面试题:
function fun(){ var count=1; return function fun2(){ count++ console.log(count) }}var fun2=fun()fun2() //2fun2() //3fun2() //4扩展理解:模块作用域的闭包
// myModule.jslet x = 5;export const getX = () => x;export const setX = (val) => { x = val;};import { getX, setX } from "./myModule.js";console.log(getX()); // 5setX(6);console.log(getX()); // 6模块导出一对 getter-setter 函数,它们在模块作用域变量 x 上创建了闭包。即便在其他模块中不能直接访问 x 的情况下,也能通过函数对 x 进行读写。
文章版权声明:除非注明,否则均为边学边练网络文章,版权归原作者所有