前言
对于JavaScript而言,var a = 2; 是两个操作。var a 是编译阶段的任务,而 a = 2 是执行阶段的任务。因此,在代码被执行前,所有的声明都会被“移动”到各自作用域的最顶端。这个过程就是“提升”。
一、变量声明与赋值?
声明在前,赋值在后。
只有声明本身会被提升,而赋值或其他运行逻辑会留在原地。
console.log(a); // undefined
var a = 10;
// 等价于
var a;
console.log(a); // undefined
a = 10;
二、函数声明
函数声明本身会被提升,但函数表达式的赋值在内的操作并不会被提升(可理解为普通变量被赋值函数的操作)。
// 函数提升
bar(); // 1
function bar(){
console.log("1");
}
// 等价于
function bar(){
console.log("1");
}
bar(); // 1
// 函数表达式提升
foo(); // TypeError
bar(); // ReferenceError
var foo = function bar(){
//...
}
// 等价于
var foo;
foo(); // TypeError
bar(); // ReferenceError
foo = function(){
var bar = ...
}
三、函数优先
函数提升优先,普通变量提升靠后。
下面示例:由于函数声明会被提升到普通变量之前,因此后续的 var foo 是重复声明而被忽略。
foo(); // 1
var foo;
function foo() {
console.log("1");
};
foo = function() {
console.log("2");
};
// 等价于
function foo() {
console.log("1");
};
foo(); // 1
foo = function() {
console.log("2");
};
总结
注意避免重复声明,尤其是当普通的 var 声明和函数声明混合在一起,否则会引起很多问题!