变量与作用域
在本课程中,你将学习现代 JavaScript 中变量和作用域的工作原理。
变量
变量是一个带有唯一名称的命名容器,用于存储数据值。下面的语句声明了一个名为 "car" 的变量:
1let car; 2 3console.log(car); // undefined
在 JavaScript 中,变量在创建时会自动初始化为 undefined 值。你可以在声明变量时使用赋值运算符 (=) 为其赋值:
1let car = 'Volvo'; 2 3console.log(car); // Volvo
在使用变量之前,请务必先对其进行初始化,否则会引发错误:
1console.log(car); // ReferenceError: car is not defined 2 3let car = 'Toyota';
ECMAScript 2015(简称 ES6)引入了两种新的变量声明方式:let 和 const。这些新关键字的引入是为了修复由 var 的函数作用域带来的混淆问题。
作用域
所谓作用域,指的是在程序运行期间,变量在代码不同部分的可见性。换句话说,作用域是指代码中可以访问和修改某个变量的部分。
在 JavaScript 中,有两种类型的作用域:
- 全局作用域
- 局部作用域
现代 JavaScript 的变化主要体现在局部作用域中变量的使用方式上。

全局作用域
在函数外部声明的变量属于全局作用域。这意味着它可以在代码的任何地方被访问和修改。
你可以在全局作用域中声明常量:
1const COLS = 10; 2const ROWS = 20;
这些常量可以从代码的任意部分访问。
局部作用域
在局部作用域中声明的变量无法从该作用域外部访问。同一个变量名可以在不同的作用域中重复使用,因为它们绑定于各自的作用域。
局部作用域的具体行为取决于所使用的变量声明方式。
函数作用域
使用 var 关键字声明的变量具有函数作用域。它们只能在声明它的函数内部访问。
1function printCar() { 2 if(true) { 3 console.log(car); // undefined 4 var car = "Porsche"; 5 console.log(car); // "Porsche" 6 } 7 console.log(car); // "Porsche" 8} 9 10printCar(); 11console.log(car); // ReferenceError
可以看到,即使在声明之前访问 car,也不会报错。这是因为使用 var 声明的变量会被提升(hoisting),即在函数顶部被移动并初始化为 undefined,因此在函数作用域内无论位置如何都能访问到。
这可能会让人感到困惑。如果你不完全理解这一点,也不用担心;本课程中不会使用 var 的函数作用域。但了解它的存在是有帮助的。
块作用域
ES6 引入了块作用域的概念,通过新的变量声明方式 const 和 let 实现。这意味着变量的有效范围是两个大括号 {} 之间,例如在 if 或 for 语句内部。
1function printCar() { 2 if(true) { 3 console.log(car); // ReferenceError 4 const car = "Fiat"; 5 console.log(car); // "Fiat" 6 } 7 console.log(car); // ReferenceError 8} 9 10printCar(); 11console.log(car); // ReferenceError
let 和 const 声明的变量直到其定义被执行后才会被初始化,它们不会像 var 那样被提升。在初始化之前访问它们会导致 ReferenceError。
这种方式更清晰易懂。本课程中将使用 let 和 const 的块作用域。
const 与 let 的区别
现在我们知道应该使用 let 和 const,那么该选择哪一个?
两者的区别在于:const 声明的变量值不能通过重新赋值更改,也不能重新声明。因此,如果不需要重新赋值,就应该使用 const。这也能让代码更清晰,因为一个变量只代表一个事物。
你可以始终先将变量声明为 const,直到发现需要重新赋值时再改为 let。一个需要使用 let 的典型场景是在循环中:
1for(let i = 0; i < 10; i++) { 2 console.log(i); // 0, 1, 2, 3 ... 3}
总结
-
在全局作用域中声明的变量可以在代码的任何地方访问。
-
在局部作用域中声明的变量无法从该作用域外部访问。
-
对于值永远不会改变的变量,优先使用
const。 -
其他情况使用
let。 -
避免使用
var,以减少混淆。
变量与作用域测验
Quiz
const 和 let 具有哪种作用域?