MST

星途 面试题库

面试题:JavaScript函数提升与作用域:作用域链与闭包中的函数提升

考虑以下代码: ```javascript function outer() { let x = 10; function inner() { console.log(x); } return inner; } let closure = outer(); function x() { return 'I am a function'; } closure(); ``` 请详细解释输出结果以及在这个过程中函数提升、作用域链和闭包是如何相互作用的。
29.7万 热度难度
编程语言JavaScript

知识考点

AI 面试

面试题答案

一键面试
  1. 输出结果
    • 输出结果为 10
  2. 函数提升
    • 在JavaScript中,函数声明会被提升到其所在作用域的顶部。在上述代码中,function x() { return 'I am a function'; } 是一个函数声明,它会被提升到全局作用域的顶部。但是,这并不会影响 closure 函数内部对 x 的查找。因为 closure 函数形成的闭包作用域链中,首先查找自己内部作用域(这里 inner 函数没有自己的 x 变量声明),然后查找其外部函数 outer 的作用域,找到了 let x = 10; 声明的 x 变量。而全局作用域中的 x 函数声明,在 closure 函数的作用域链查找过程中,不会被找到,因为 closure 函数的作用域链在找到 outer 函数作用域中的 x 变量后就停止查找了。
  3. 作用域链
    • closure 函数被调用时,JavaScript引擎会沿着作用域链查找变量 x。作用域链是由函数的词法作用域决定的。closure 函数(即 inner 函数)的作用域链首先包含它自己的作用域(这里为空,因为 inner 函数没有声明任何局部变量),然后包含 outer 函数的作用域(在这里找到了 let x = 10; 声明的 x 变量),再往上是全局作用域。所以在 closure() 调用时,会找到 outer 函数作用域中的 x 变量并输出其值 10
  4. 闭包
    • 闭包是指函数能够记住并访问其词法作用域,即使函数在其词法作用域之外被调用。在上述代码中,inner 函数(赋值给 closure)形成了闭包。inner 函数在 outer 函数外部被调用(closure()),但它仍然能够访问 outer 函数作用域中的变量 x。这是因为当 outer 函数返回 inner 函数时,inner 函数的作用域链中保留了对 outer 函数作用域的引用,使得 inner 函数在 outer 函数执行完毕后,依然可以访问 outer 函数作用域中的变量 x