JavaScript:var、let和const的区别_js var let const的区别
在 JavaScript 中,变量声明主要有三种关键字:var
, let
, 和 const
。它们各有不同的作用域、提升行为和赋值限制。以下是详细对比:
📌 1. var
(传统变量声明)
特点:
- 函数作用域:在整个函数内部有效
- 变量提升:声明会被提升到作用域顶部,但赋值不会
- 可重复声明:同一作用域内允许重复声明
- 可修改:声明后可以重新赋值
- 全局属性:在全局作用域声明的变量会成为
window
对象的属性
console.log(a); // undefined (变量提升)var a = 10; var a = 20; // 允许重复声明function test() { var b = \"scope\";}console.log(b); // ReferenceError (函数作用域限制)
🚫 2. let
(ES6块级变量声明)
特点:
- 块级作用域:只在
{}
代码块内有效 - 暂时性死区 (TDZ):声明前访问会报错
- 禁止重复声明:同一作用域内不可重复声明
- 可修改:声明后可以重新赋值
console.log(x); // ReferenceError (TDZ)let x = 5;{ let y = \"block\";}console.log(y); // ReferenceErrorlet z = 10;let z = 20; // SyntaxError (禁止重复声明)
🔒 3. const
(ES6常量声明)
特点:
- 块级作用域:同
let
- 初始化必赋值:声明时必须赋值
- 禁止重复声明/赋值:不可重新赋值
- 引用类型内容可变:对象/数组内部值可修改(指针不变)
- 暂时性死区:同
let
const PI = 3.14;PI = 3; // TypeErrorconst obj = { name: \"John\" };obj.name = \"Anna\"; // ✅ 允许修改属性const arr = [1, 2];arr.push(3); // ✅ 修改数组内容
🔍 关键区别汇总
var
let
const
let
🎯 使用建议
const
let
let
var
黄金法则:优先使用
const
→ 需要重新赋值时用let
→ 避免使用var
⚠️ 常见误区
// 陷阱1:const 的对象属性可变const user = { name: \"Alice\" };user.name = \"Bob\"; // ✅ 允许// 陷阱2:for 循环中 var 的行为for (var i = 0; i < 3; i++) { setTimeout(() => console.log(i), 100); // 输出 3,3,3}// 解决:改用 letfor (let j = 0; j < 3; j++) { setTimeout(() => console.log(j), 100); // 输出 0,1,2}
掌握这三种声明方式的差异,能够帮助您编写更安全、可预测的 JavaScript 代码!🏆
在 JavaScript 中,除了常见的 var
、let
和 const
之外,还有以下几种变量声明和值绑定方式:
1. 全局变量声明(不推荐)
- 不使用任何关键字声明
- 在非严格模式下直接赋值创建全局变量
- 这是最不安全的声明方式(容易造成变量污染)
noKeywordVariable = 42; // 自动成为全局对象的属性(浏览器中是 window)console.log(noKeywordVariable); // 42console.log(window.noKeywordVariable); // 浏览器中输出 42
2. 函数参数声明
- 函数参数本身就是局部变量声明
- 行为类似
var
(在 ES5 及之前)或let
(在 ES6 严格模式)
function example(a, b) { a = 5; // 可以重新赋值 console.log(a); // 5}
3. function
声明(函数声明)
- 使用
function
关键字声明函数 - 具有提升行为(可在声明前调用)
myFunction(); // 正常工作(函数声明提升)function myFunction() { console.log(\"Hello!\");}
4. class
声明(ES6+)
- 创建类构造函数
- 类似
let
的块级作用域(但有提升限制)
class MyClass { // 类定义}const instance = new MyClass();
5. import
声明(ES6 模块)
- 导入模块绑定
- 行为类似
const
(不可重新赋值)
// 在模块中import { someExport } from \'./module.js\';import * as utils from \'./utilities.js\';
6. export
声明(ES6 模块)
- 导出变量绑定
- 不是传统声明方式,但创造了可导出的绑定
// 在模块中export const apiKey = \'123-ABC\';export function getData() { ... }
7. 解构赋值声明
- 不是独立的声明方式,但结合其他关键字使用
- 可一次性声明多个变量
// 对象解构const { name, age } = person;// 数组解构const [first, second] = items;
8. try...catch
中的 catch 参数
catch
块中的错误参数创建块级作用域变量
try { throw new Error(\"Test\");} catch (err) { // err 变量只在此块内有效 console.log(err.message);}
9. 函数表达式赋值
- 使用函数表达式而非函数声明
- 绑定到变量名上
const myFunction = function() { console.log(\"Function expression\");};
总结比较表
var
let
const
import
在实践中,建议:
- 优先使用
const
声明 - 需要重新赋值时用
let
- 避免使用
var
和无关键字声明 - 使用模块导入导出管理跨文件变量
- 利用解构赋值简化声明过程
这些不同的声明方式共同构成了 JavaScript 灵活但需要谨慎使用的变量系统。