在 JavaScript 中,let 和 var 都是用于声明变量的关键字,但它们在作用域、提升和重复声明等方面有重要区别。let 和 var 的核心区别在于作用域和变量提升。var 是函数作用域,声明的变量在整个函数内有效,且会提升到作用域顶部。而 let 是块级作用域,仅在声明所在的代码块内有效,且存在“暂时性死区”,访问未初始化的 let 变量会直接报错。
javascript中let和var的区别
1. 作用域
var:
具有函数作用域,即在函数内部声明的变量在整个函数内有效,即使声明在代码块的末尾,也能在块外访问。
示例:
javascriptfunction example() {if (true) {var x = 10;}console.log(x); // 10(x 在 if 块外仍可访问)}
let:
具有块级作用域,仅在声明所在的代码块(如 {}、if、for)内有效。
示例:
javascriptfunction example() {if (true) {let y = 10;}console.log(y); // ReferenceError: y is not defined}
2. 变量提升
var:
变量会提升到函数或全局作用域的顶部,但初始化值为 undefined。
示例:
javascriptconsole.log(a); // undefined(不会报错,但值为 undefined)var a = 5;
let:
变量也会提升,但不会初始化,进入“暂时性死区”(Temporal Dead Zone, TDZ),访问会报错。
示例:
javascriptconsole.log(b); // ReferenceError: Cannot access 'b' before initializationlet b = 5;
3. 重复声明
var:
允许在同一作用域内重复声明变量(不会报错,但可能引发意外覆盖)。
示例:
javascriptvar c = 1;var c = 2; // 合法,c 被覆盖
let:
同一作用域内不允许重复声明(会抛出 SyntaxError)。
示例:
javascriptlet d = 1;let d = 2; // SyntaxError: Identifier 'd' has already been declared
4. 全局对象属性
var:
在全局作用域中声明的变量会成为 window 对象的属性(浏览器环境)。
示例:
javascriptvar e = 10;console.log(window.e); // 10
let:
不会添加到全局对象中。
示例:
javascriptlet f = 10;console.log(window.f); // undefined
总结对比表
特性varlet
作用域函数作用域块级作用域
变量提升提升并初始化为 undefined提升但不初始化
重复声明允许不允许
全局对象属性成为 window 的属性不成为 window 的属性
最佳实践
默认使用 let,避免 var 的潜在问题。
需要全局变量时,显式挂载到 window 对象。
在循环或条件块中优先用 let,确保变量作用域隔离。
示例:
javascript// 推荐使用 letfor (let i = 0; i < 3; i++) {setTimeout(() => console.log(i), 100); // 0, 1, 2}// 避免 var 的循环问题for (var j = 0; j < 3; j++) {setTimeout(() => console.log(j), 100); // 3, 3, 3(j 被共享)}
var 允许同一作用域内重复声明变量,可能意外覆盖,且全局声明的 var 会成为 window 对象的属性。而 let 禁止重复声明,且全局声明的 let 不会绑定到 window。现代开发中,推荐优先使用 let以避免作用域污染和变量提升问题。