【高频面试题】暴击!这道“简单”的闭包题,90%的前端都答错了(附原理详解)

89 阅读3分钟

💡 写在前面

闭包,这个老生常谈的JavaScript核心概念,是每个前端工程师的必经之路。它看似简单,却在面试中让无数英雄折腰。今天,我们不聊干巴巴的理论,直接上一道“有毒”的代码题。据说,只有10%的人能一次完全答对!

你敢来挑战吗?

🚀 挑战开始:神奇的“计数器工厂”

假设我们有一个“计数器工厂”函数,它应该能生成多个独立的计数器。请看下面的代码: `

image.png

第一问(基础题):请问上述五个 console.log 的输出分别是什么?

思考10秒钟...

答案: 6,6,6,6,6 恭喜你,如果答对了!但这只是热身。

屏幕截图 2025-11-18 184713.png

🔥 灵魂拷问升级版

现在,我们稍微修改一下代码,情况就变得复杂了:

屏幕截图 2025-11-18 184313.png 第二问(进阶题)聪明的你能想到正确答案吗

屏幕截图 2025-11-18 184320.png

💎 原理深度解析

第一问的解析:为什么是 五个6

var声明的变量具有 函数作用域 ,而不是块级作用域。这意味着整个for循环中只有一个i变量实例。循环结束后i的值变为6: 当i=5时,条件i<=5满足,执行完循环体后,i自增为6,然后条件不满足,循环结束。此时i的值是6。

**第二问的解析:为什么是1,2,3,4,5

本来正常的函数代码执行完毕后就会被销毁的,当函数是嵌套函数时当调用一个外部函数中返回的内部函数后,即使外部函数执行结束,但是内部函数依然引用了外部函数的变量,那么外部函数的执行上下文就不能完全销毁,而是会保留一个集合,用来装内部函数需要引用的变量,如图

37706371-390C-486B-AB22-88AD9FFD85DD.png 所以此时V8在当前作用域中查找一个变量,如果找不到,就会去上一级作用域中查找,而outer指针来记录该作用域的外层作用域是谁,此时的上一级作用域就是图中所示的闭包。

🎯 总结与启示

1.一个函数执行完毕后,它的执行上下文会从调用栈中被销毁

2.一个函数的内部函数一定有权力访问该外部函数的变量(作用域)

当调用一个外部函数中返回的内部函数后,即使外部函数执行结束,但是内部函数依然引用了外部函数的变量,那么外部函数的执行上下文就不能完全销毁,而是会保留一个集合,用来装内部函数需要引用的变量,我们把集合称之为闭包。

真正理解闭包,不仅能让你在面试中游刃有余,更能让你在开发中避免无数稀奇古怪的Bug(比如循环中绑定事件)。你,学废了吗?