function、var、let 和 const 用于不同的声明场景
在JavaScript中,function
、var
、let
和 const
用于不同的声明场景,具有以下核心区别:
1. 作用域
-
function
和var
:函数作用域(Function Scope)。-
在函数内部声明的变量或函数,仅在该函数内有效。
-
在块(如
if
、for
)中声明的var
变量会提升到函数或全局作用域。
-
-
let
和const
:块级作用域(Block Scope)。-
仅在最近的
{}
内有效(如if
、for
、函数等)。
-
示例:
javascript
复制
function example() { if (true) { var a = 1; // 函数作用域 let b = 2; // 块作用域 const c = 3; // 块作用域 } console.log(a); // 1 console.log(b); // ReferenceError console.log(c); // ReferenceError }
2. 变量提升(Hoisting)
-
function
:整体提升,可在声明前调用。 -
var
:变量名提升(初始化为undefined
),赋值留在原地。 -
let
和const
:无提升,存在暂时性死区(TDZ),声明前访问会报错。
示例:
javascript
复制
console.log(func); // undefined(var提升) var func = function() {}; foo(); // 正常执行(函数整体提升) function foo() {} console.log(x); // ReferenceError(TDZ) let x = 5;
3. 重复声明
-
var
:允许重复声明,后者覆盖前者。 -
function
:允许重复声明,后者覆盖前者。 -
let
和const
:禁止重复声明(同一作用域内)。
示例:
javascript
复制
var a = 1; var a = 2; // 合法 let b = 3; let b = 4; // SyntaxError
4. 全局作用域行为
-
var
:在全局作用域声明的变量会成为全局对象(如window
)的属性。 -
let
和const
:全局变量不与全局对象绑定。
示例:
javascript
复制
var globalVar = 1; console.log(window.globalVar); // 1 let globalLet = 2; console.log(window.globalLet); // undefined
5. const
的特殊性
-
必须初始化赋值。
-
不可重新赋值,但对象或数组的内容可修改。
示例:
javascript
复制
const obj = { a: 1 }; obj.a = 2; // 允许 obj = {}; // TypeError(不可重新赋值)
6. 循环中的表现
-
var
:循环变量泄露到外部,闭包可能捕获同一变量。 -
let
:每次迭代创建新的绑定,适合闭包场景。
示例:
javascript
复制
for (var i = 0; i < 3; i++) { setTimeout(() => console.log(i), 0); // 输出 3, 3, 3 } for (let j = 0; j < 3; j++) { setTimeout(() => console.log(j), 0); // 输出 0, 1, 2 }
使用建议
-
默认用
const
:防止意外修改,提升代码可读性。 -
需要重新赋值时用
let
:如循环计数器、状态变量。 -
避免使用
var
:优先使用块级作用域(let
/const
)。 -
function
的替代:可用const func = () => {}
形式,避免提升的副作用。
总结表格
特性 | function | var | let | const |
---|---|---|---|---|
作用域 | 函数/全局 | 函数/全局 | 块级 | 块级 |
提升 | 整体提升 | 变量名提升 | 无 | 无 |
重复声明 | 允许 | 允许 | 禁止 | 禁止 |
重新赋值 | 可覆盖 | 允许 | 允许 | 禁止(对象内容可修改) |
全局对象属性 | 是(函数名) | 是 | 否 | 否 |
暂时性死区 | 无 | 无 | 有 | 有 |
通过理解这些差异,可以编写更安全、可维护的代码。