JavaScript变量声明提升
JavaScript 中的 变量声明提升(Hoisting) 是 JavaScript 引擎在代码执行前将变量和函数声明提升到作用域顶部的行为。理解变量声明提升有助于避免代码中的潜在错误。
1. 变量声明提升的原理
- 提升(Hoisting):JavaScript 引擎在代码执行前会扫描整个作用域,将变量和函数声明提升到作用域的顶部。
- 仅提升声明:变量的赋值操作不会被提升,只有声明部分会被提升。
2. 变量声明提升的行为
(1) var 声明的变量
- 提升:声明会被提升到作用域顶部,但赋值不会。
- 初始值:提升后的变量值为
undefined。
示例:
console.log(a); // 输出:undefined(声明提升,但未赋值)
var a = 10;
console.log(a); // 输出:10
实际执行顺序:
var a; // 声明提升
console.log(a); // 输出:undefined
a = 10; // 赋值
console.log(a); // 输出:10
(2) let 和 const 声明的变量
- 提升:声明会被提升,但不会初始化(进入“暂时性死区”)。
- 初始值:在声明前访问会抛出
ReferenceError。
示例:
console.log(b); // 报错:ReferenceError: Cannot access 'b' before initialization
let b = 20;
console.log(b); // 输出:20
实际执行顺序:
let b; // 声明提升,但未初始化
console.log(b); // 报错:暂时性死区
b = 20; // 赋值
console.log(b); // 输出:20
3. 函数声明提升
(1) 函数声明
- 提升:整个函数声明(包括函数体)会被提升到作用域顶部。
- 行为:可以在声明前调用。
示例:
foo(); // 输出:Hello
function foo() {
console.log('Hello');
}
实际执行顺序:
function foo() {
console.log('Hello');
}
foo(); // 输出:Hello
(2) 函数表达式
- 提升:只有变量声明会被提升,函数赋值不会被提升。
- 行为:在赋值前调用会报错。
示例:
bar(); // 报错:TypeError: bar is not a function
var bar = function() {
console.log('World');
};
实际执行顺序:
var bar; // 声明提升
bar(); // 报错:bar 是 undefined
bar = function() {
console.log('World');
};
4. 变量声明提升的作用域
- 函数作用域:
var声明的变量会提升到函数作用域顶部。 - 块级作用域:
let和const声明的变量会提升到块级作用域顶部,但在声明前不可访问。
示例:
function test() {
console.log(x); // 输出:undefined
if (true) {
var x = 10;
let y = 20;
}
console.log(x); // 输出:10
console.log(y); // 报错:ReferenceError: y is not defined
}
test();
5. 变量声明提升的注意事项
-
避免使用未声明的变量:未声明的变量不会提升,直接使用会报错。
console.log(z); // 报错:ReferenceError: z is not defined -
避免重复声明:
var允许重复声明,后声明的变量会覆盖前者。let和const不允许重复声明,会报错。
示例:
var a = 1; var a = 2; // 允许 console.log(a); // 输出:2 let b = 1; let b = 2; // 报错:SyntaxError: Identifier 'b' has already been declared -
优先使用
let和const:let和const提供了块级作用域,避免了var的变量提升问题。
总结
| 声明方式 | 提升行为 | 初始值 | 作用域 |
|---|---|---|---|
var | 声明提升,赋值不提升 | undefined | 函数作用域 |
let | 声明提升,但进入暂时性死区 | 不可访问 | 块级作用域 |
const | 声明提升,但进入暂时性死区 | 不可访问 | 块级作用域 |
| 函数声明 | 整个函数(包括函数体)提升 | 函数体 | 函数作用域 |
| 函数表达式 | 仅变量声明提升,函数体不提升 | undefined | 函数作用域 |
理解变量声明提升有助于编写更健壮的 JavaScript 代码,避免因变量作用域和声明顺序导致的错误。
更多vue相关插件及后台管理模板可访问vue admin reference,代码详情请访问github