JavaScript闭包工作原理:为何需先调用g()才能使用f()?
问题解答
1. 闭包的工作原理
你的代码里的闭包是这样运作的:
当g()被调用时,会创建一个局部作用域,里面定义了变量a = 23。接着,全局变量f被赋值为一个新的函数,这个函数内部引用了g作用域里的a。
即使g()执行完毕、其局部作用域本应被销毁,f指向的这个函数依然能访问到a——这就是闭包的核心:函数会保留它创建时所在的作用域链,哪怕创建它的作用域已经执行结束。当你调用f()时,它会沿着作用域链找到g里的a,计算并输出23*2=46。
2. f是否仅在初始化g之后才生成?
准确来说,f是一个提前声明的全局变量(用let f声明,初始值为undefined),只有当g()被调用时,f才会被赋值为那个带闭包的函数。在g()执行前,f只是一个未赋值的变量,并不是可执行的函数。
3. 为什么必须先调用g()才能调用f()?这和执行上下文有关吗?
是的,这和执行上下文直接相关:
- 在代码刚开始执行时,全局执行上下文被创建,
f被声明但未赋值,g被赋值为一个函数。此时f的值是undefined,如果你直接调用f(),会抛出TypeError: f is not a function的错误。 - 只有当你调用
g()时,才会创建g的函数执行上下文:在这个上下文里,会执行f = function() {...}的赋值操作,把带闭包的函数赋值给全局的f。这时候f才变成一个可执行的函数,调用f()才会正常工作。
你调换调用顺序后出现问题,本质就是f还没被赋值为函数就被调用了,和闭包本身无关,纯粹是变量赋值的时机问题。
内容的提问来源于stack exchange,提问作者Jules Mundur
相关产品推荐
相关产品推荐

