返回

展望未来的 JavaScript 编程:深入了解 let 变量的顶层作用域

前端

前言:let 变量的作用域

JavaScript 中的 let 变量自 ES6 引入以来,便以其块级作用域特性在前端开发中大放异彩。与 var 变量不同,let 变量的作用域仅限于其所在的花括号代码块,这使得代码更加清晰和易于维护。

顶层作用域中的 let 变量

然而,当 let 变量被声明在顶层作用域(即没有包含在任何函数或代码块内)时,其行为却与我们的直觉大相径庭。为了更好地理解这一点,让我们先来看一个简单的代码示例:

console.log(fn); // undefined
console.log(variable); // undefined
function fn() {
  console.log(variable); // 1
}
let variable = 1;

执行这段代码,打印结果分别为:undefined、undefined、1。以 JS 语句顺序执行的前提来看,前两行代码执行时 fn 函数和 variable 变量都还没有被声明,应该抛出错误才对,得到的结果并不符合直觉。这种现象就被称为函数提升(Function Hoisting)或变量提升(Variable Hoisting)。

函数提升与变量提升

函数提升是指在 JavaScript 中,函数声明会被提升到其所在作用域的顶部,而变量声明则会被提升到其所在作用域的顶部并初始化为 undefined。这意味着,无论函数或变量在代码中的实际位置,它们都会被提升到作用域的顶部,并在该作用域内有效。

回到前面的代码示例,由于 fn 函数和 variable 变量都被提升到了顶层作用域的顶部,因此在执行 console.log(fn) 和 console.log(variable) 时,它们的值都为 undefined。而当执行 function fn() { console.log(variable); } 时,variable 变量已经通过 let 声明并初始化为 1,因此在函数体内 console.log(variable) 的输出结果为 1。

let 变量的“前世今生”

为了更好地理解 let 变量在顶层作用域中的行为,我们需要从 let 的“前世今生”说起。在 ES6 之前,JavaScript 中只有 var 变量,而 var 变量具有全局作用域或函数作用域。这意味着,如果 var 变量在顶层作用域中声明,那么它将在整个脚本中有效。

ES6 引入了 let 变量,并对其作用域进行了严格限制。let 变量只能在声明所在的代码块内使用,如果在代码块外引用,则会抛出错误。然而,在顶层作用域中声明的 let 变量却仍然会受到函数提升的影响,因此在执行时会被提升到作用域的顶部。

结语:谨慎使用 let 变量

综上所述,let 变量在顶层作用域中的行为可能会出乎意料,因此在使用时需要格外谨慎。为了避免意外情况,建议开发者尽量避免在顶层作用域中声明 let 变量,或者在声明时使用 const 变量来代替。const 变量与 let 变量类似,但其值一旦声明后就无法修改。