MST
星途 面试题库

面试题:JavaScript变量声明提升与作用域链的结合考察

分析以下代码的输出结果,并解释原因。代码如下:function test() { console.log(a); var a = 1; console.log(a); let b = 2; console.log(b); { let b = 3; console.log(b); } console.log(b); } test(); 说明var和let声明变量在这个代码执行过程中,与作用域链、变量提升相关的原理。
39.2万 热度难度
编程语言JavaScript

知识考点

AI 面试

面试题答案

一键面试
  1. 输出结果

    • undefined
    • 1
    • 2
    • 3
    • 2
  2. 原因分析

    • var 变量提升:在函数 test 中,var a = 1; 由于 var 存在变量提升,所以 a 的声明被提升到函数作用域的顶部,但初始化 a = 1 不会提升。因此,第一个 console.log(a); 输出 undefined。之后 a 被赋值为 1,第二个 console.log(a); 输出 1
    • let 块级作用域let b = 2; 声明了一个块级作用域的变量 b。在函数中,从声明处开始 b 才是有效的。所以第三个 console.log(b); 输出 2
    • 内层 let 块级作用域{ let b = 3; } 创建了一个新的块级作用域,在此块级作用域内 b 被重新声明并赋值为 3,所以第四个 console.log(b); 输出 3。当离开这个块级作用域后,这个 b 就失效了,所以第五个 console.log(b); 输出的是外层块级作用域中声明的 b 的值 2
  3. var 与作用域链、变量提升原理

    • 变量提升var 声明的变量会被提升到其所在函数作用域(全局作用域如果在全局环境声明)的顶部,但赋值操作不会提升。这意味着在变量声明之前访问该变量,会得到 undefined
    • 作用域链:当在函数中访问一个变量时,首先会在函数的局部作用域中查找,如果找不到,就会沿着作用域链向上一级作用域查找,直到全局作用域。例如在 test 函数中访问 a,先在函数局部作用域(因为 avar 声明在函数内)查找,由于变量提升提前声明了 a,所以能找到,尽管此时还未赋值。
  4. let 与作用域链、变量提升原理

    • 不存在变量提升let 声明的变量不存在变量提升,在声明之前访问会导致“暂时性死区”错误。例如如果在 let b = 2; 之前访问 b 就会报错。
    • 块级作用域let 声明的变量具有块级作用域,它只在包含它的块({})内有效。这与 var 的函数作用域不同,例如在 { let b = 3; } 这个块内声明的 b 只在这个块内有效,出了这个块就无法访问。作用域链的查找规则同样适用,例如在内部块访问变量,先在内部块查找,找不到再沿作用域链向上查找。