前言:
- 变量提升是 JavaScript 中的一种特殊行为,指在执行代码前将变量和函数声明提升到当前作用域的顶部,因此可以在声明位置之前的代码使用这些变量或函数
- 变量提升是 JavaScript 中的一个重要特性,可以在一定程度上减少变量的声明过程,但同时也容易造成代码中的混乱和错误。因此在开发过程中,需要格外注意变量和函数的声明和使用顺序,尽量减少因变量提升导致的错误。
1.变量提升与作用域
在 JavaScript 中,变量分为全局变量和局部变量。全局变量声明在代码的最外层,属于全局作用域;局部变量声明在函数内部,属于函数作用域。
变量提升与作用域的关系如下:
全局变量声明会提升到全局作用域的顶部,因此可以在全局作用域中的任意位置使用该变量。
函数内部使用 var 关键字声明的变量,会提升到函数作用域的顶部,因此可以在函数内部的任意位置使用该变量。
例如:
console.log(a); // undefined
var a = 1;
console.log(a); // 1
function foo() {
console.log(b); // undefined
var b = 2;
console.log(b); // 2
}
foo();
上述代码中,变量 a 和 b 都是使用 var 关键字声明的。在全局作用域中,变量 a 的声明会被提升到全局作用域的顶部,因此第一个 console.log 语句输出 undefined,而第二个 console.log 语句输出 1。
在函数 foo 中,变量 b 的声明也会被提升到函数作用域的顶部,因此第一个 console.log 语句同样输出 undefined,而第二个 console.log 语句输出 2。
需要注意的是,变量提升只提升声明,不提升赋值。因此在以下代码中:
console.log(c); // undefined
var c = 3;
//变量 c 的声明会被提升到全局作用域的顶部,但是赋值操作是在 console.log 语句之后进行的,因此 console.log 输出 undefined。
2.函数提升
同样地,JavaScript 中的函数声明也会在作用域的顶部进行提升,因此可以在函数声明之前的代码中使用该函数。
例如:
foo(); // "foo"
function foo() {
console.log("foo");
}
在上述代码中,函数 foo 的声明会被提升到全局作用域的顶部,因此在函数声明之前就可以使用该函数。
需要注意的是,函数声明和函数表达式是不同的。函数声明在解析时就会提升到作用域的顶部;而函数表达式则会像变量赋值一样,在代码执行到该语句时才会进行赋值操作,并且只有在赋值完成后才能调用该函数。
例如:
foo(); // "TypeError: foo is not a function"
var foo = function() { console.log("foo"); }
在上述代码中,函数 foo 是使用函数表达式进行赋值的,因此 foo 只有在函数表达式赋值完成后才会被定义,此时已经超过了调用 foo 的代码位置,因此会抛出 TypeError 错误。