推荐答案
let
和 const
是 ES6 引入的用于声明变量的关键字,它们与 var
的主要区别在于:
作用域:
var
声明的变量具有函数作用域(function scope),即在函数内部声明的变量在整个函数内部都可用,如果在函数外部声明则为全局作用域。let
和const
声明的变量具有块级作用域(block scope),即变量只在声明它们的代码块(例如if
语句、for
循环、{}
包裹的代码)内部可用。
变量提升(Hoisting):
var
声明的变量存在变量提升,即在声明语句之前就可以访问,只是值为undefined
。let
和const
声明的变量不存在变量提升,如果在声明语句之前访问,会抛出ReferenceError
错误,形成“暂时性死区”(Temporal Dead Zone,TDZ)。
重复声明:
var
允许在同一作用域内重复声明同一个变量,后面的声明会覆盖前面的。let
和const
在同一作用域内不允许重复声明同一个变量,会抛出SyntaxError
错误。
变量修改:
var
和let
声明的变量的值可以被修改。const
声明的变量必须在声明时初始化,并且其值不能被重新赋值。但是,如果const
声明的是一个对象或数组,那么对象或数组的内容是可以被修改的。
特性 var let const 作用域 函数作用域 块级作用域 块级作用域 变量提升 有 无(TDZ) 无(TDZ) 重复声明 允许 不允许 不允许 值修改 允许 允许 不允许(基本类型),允许(引用类型)
本题详细解读
1. 作用域差异:函数作用域 vs. 块级作用域
var 的函数作用域:
var
声明的变量在函数内定义时,其作用域限定在整个函数内部。如果在函数外定义,则为全局作用域。这意味着,即使在函数内部的某个代码块中声明 var
变量,它在该函数的所有位置都是可以被访问的。这会导致一些潜在的问题,比如变量覆盖。
function exampleVar() { if (true) { var x = 10; // x 在整个函数内部都是可访问的 } console.log(x); // 输出 10 } exampleVar(); console.log(typeof x) //输出 "undefined" x的作用域只在函数内部
let 和 const 的块级作用域:
let
和 const
声明的变量的作用域被限定在最近的代码块内。这包括 if
,for
, while
循环和任何由花括号 {}
包裹的代码块。这样的设计可以更好地控制变量的可见性,避免变量冲突,使代码更清晰。
-- -------------------- ---- ------- -------- ----------------- - -- ------ - --- - - --- ----- - - --- --------------- -- -- -- -------------- -- -- -- - ----------------- -- ------------------ - -- --- ------- ----------------- -- ------------------ - -- --- ------- - ------------------
2. 变量提升(Hoisting)
var 的变量提升:
var
声明的变量会在代码执行前被 “提升” 到当前作用域的顶部。这意味着你可以在声明变量之前使用它,但其值会是 undefined
,直到执行到声明语句时才会被赋值。
console.log(myVar); // 输出 undefined var myVar = 40; console.log(myVar); // 输出 40
let 和 const 的暂时性死区:
let
和 const
声明的变量不会被提升,如果在声明之前访问,会抛出一个 ReferenceError
,表示该变量尚未被声明。这个区域被称为 “暂时性死区”(TDZ)。
//console.log(myLet); // 报错:ReferenceError: Cannot access 'myLet' before initialization let myLet = 50; console.log(myLet); // 输出 50 //console.log(myConst); // 报错:ReferenceError: Cannot access 'myConst' before initialization const myConst = 60; console.log(myConst) //输出 60
3. 重复声明
var 允许重复声明:
var
允许在同一个作用域内多次声明同一个变量,后面的声明会覆盖前面的声明,这可能会导致意想不到的错误。
var a = 1; var a = 2; console.log(a); // 输出 2
let 和 const 不允许重复声明:
let
和 const
在同一作用域内不允许重复声明同一个变量,这样做会抛出 SyntaxError
,这有助于防止程序中出现不必要的错误。
let b = 1; //let b = 2; // 报错:SyntaxError: Identifier 'b' has already been declared const c = 3; //const c = 4; // 报错:SyntaxError: Identifier 'c' has already been declared
4. 变量修改
var 和 let 允许修改:
var
和 let
声明的变量的值在声明后可以被多次修改。
var d = 1; d = 2; console.log(d); // 输出 2 let e = 3; e = 4; console.log(e); // 输出 4
const 不允许修改:
const
声明的变量必须在声明时初始化,并且其值不能被重新赋值。但是,如果 const
声明的是一个对象或数组,那么对象或数组的内容是可以被修改的。这是因为 const
保证的是变量指向的内存地址不发生改变,而不是保证对象或数组内容不变。
-- -------------------- ---- ------- ----- - - -- --- - -- -- ------------- ---------- -- -------- --------- ----- --- - - ----- - -- -------- - -- -- -------- ---------------------- -- -- - ----- --- - --- --- ------------ -- -------- ----------------- -- -- --- -- -- ----- - --------- -------------- ---------- -- -------- ---------