JavaScript 中的hoisting是什么?
在 JavaScript 中,hoisting(提升)是指在代码执行阶段,将变量声明和函数声明提升到它们所在作用域的顶部,但是只是提升声明本身,而不会提升赋值操作。
变量提升
对于变量声明,JavaScript 的解释器在执行代码之前会扫描整个代码块(全局作用域或函数作用域),将所有的变量声明(使用 var
关键字声明的变量)提升到顶部,但不会提升赋值操作。举例来说:
console.log(myVar); // undefined
var myVar = 10;
在这段代码中,变量 myVar
被提升到了作用域顶部,因此 console.log(myVar)
不会报错,但是输出的是 undefined
,因为赋值操作 var myVar = 10;
并没有被提升。
函数提升
对于函数声明(function declaration),整个函数体会被提升到当前作用域的顶部,因此可以在函数声明之前调用函数,例如:
foo(); // 'Hello, world!'
function foo() {
console.log('Hello, world!');
}
这是因为函数声明 function foo() { ... }
被提升到了作用域顶部,所以即使在声明之前调用 foo()
,也不会报错。
注意事项
- 只是声明提升:提升只针对变量和函数的声明,不会提升赋值操作或函数表达式(function expression)。
- 变量声明提升:使用
var
声明的变量会被提升到函数作用域的顶部或全局作用域的顶部,如果在块级作用域(如if
语句块或for
循环中使用var
)声明变量,该变量会被提升到函数作用域或全局作用域,而不是块级作用域。 - 函数声明提升:函数声明(function declaration)会被完整提升,可以在声明之前调用。而函数表达式(function expression)则不会完整提升,只会提升变量声明。
// 函数声明提升
foo(); // 'Hello from foo!'
function foo() {
console.log('Hello from foo!');
}
// 函数表达式不会完整提升
bar(); // TypeError: bar is not a function
var bar = function() {
console.log('Hello from bar!');
};
- ES6 中的 let 和 const:使用
let
和const
声明的变量也会提升,但是不会发生变量提升到块级作用域外部的情况,而是在块级作用域内部进行提升。
总之,hoisting 是 JavaScript 中的一个特性,理解它有助于避免因变量提升带来的不可预期的结果,编写更加清晰和可维护的代码。
近期评论