ES6-let-ver
ES6-let-ver
let 和 var 的作用区别总结
根据阮一峰《ECMAScript 6 入门教程》及相关资料,以下是 let
和 var
的核心区别总结:
1. 作用域规则
let
- 块级作用域:仅在声明它的代码块(
{}
)内有效,包括if
、for
、while
等语句。 - 示例:
{ let a = 1; var b = 2; } console.log(a); // 报错:a 未定义 console.log(b); // 输出 2(var 变量泄漏到外部)
- 块级作用域:仅在声明它的代码块(
var
- 函数级作用域:变量在声明它的函数或全局作用域内有效,无视代码块。
- 示例:
if (true) { var x = 5; } console.log(x); // 输出 5(var 穿透块级作用域)
2. 变量提升(Hoisting)
let
- 无变量提升:声明前访问会触发 暂时性死区(TDZ),直接报错。
- 示例:
console.log(c); // 报错:c 未初始化 let c = 3;
var
- 存在变量提升:声明前访问值为
undefined
,不会报错。 - 示例:
console.log(d); // 输出 undefined var d = 4;
- 存在变量提升:声明前访问值为
3. 重复声明
let
- 禁止重复声明:同一作用域内重复声明同一变量会报错。
- 示例:
let e = 10; let e = 20; // 报错:重复声明
var
- 允许重复声明:后声明的变量会覆盖之前的值。
- 示例:
var f = 100; var f = 200; // 正常执行,f 最终为 200
4. 全局对象属性
let
- 不绑定到全局对象:声明的全局变量不会成为
window
(浏览器)或global
(Node.js)的属性。 - 示例:
let g = 1000; console.log(window.g); // 输出 undefined(浏览器中)
- 不绑定到全局对象:声明的全局变量不会成为
var
- 绑定到全局对象:声明的全局变量会成为全局对象的属性。
- 示例:
var h = 2000; console.log(window.h); // 输出 2000(浏览器中)
5. 循环中的行为差异
let
- 独立作用域:每次迭代会创建独立的变量环境,适合闭包场景。
- 示例:
for (let i = 0; i < 3; i++) { setTimeout(() => console.log(i)); // 分别输出 0、1、2 }
var
- 共享作用域:所有迭代共享同一变量,闭包中可能捕获意外值。
- 示例:
for (var j = 0; j < 3; j++) { setTimeout(() => console.log(j)); // 全部输出 3 }
总结表格
特性 | let |
var |
---|---|---|
作用域 | 块级作用域 | 函数级作用域 |
变量提升 | 无(TDZ 报错) | 有(值为 undefined ) |
重复声明 | 禁止 | 允许 |
全局对象属性 | 不绑定 | 绑定 |
循环行为 | 独立作用域(适合闭包) | 共享作用域(可能意外值) |
延伸:const
与 let
的区别
const
声明的是常量,不可重新赋值,但非简单类型(如对象)的属性可修改。const
同样具有块级作用域、无变量提升、禁止重复声明等特性。- 示例:
const PI = 3.14; PI = 3.14159; // 报错:常量不可重新赋值 const obj = { a: 1 }; obj.a = 2; // 正常执行(修改属性) obj = {}; // 报错:常量不可重新赋值