函数声明和变量声明总是被javascript的解释器隐式的提升到包含他们的作用域的最顶端。
javascript作用域
先看下面一个C程序:
#include <stdio.h>
int main() {
int x = 1;
printf("%d, ", x); // 1
if (1) {
int x = 2;
printf("%d, ", x); // 2
}
printf("%d\n", x); // 1
}
这里会输出1 2 1是因为C系语言有块级作用域,当进入这个块时,就像是if语句,在这个块级作用域中会声明新的变量,这些变量不会影响到外部作用域。
接下来,我们看个javascript代码
var x = 1;
console.log(x); // 1
if (true) {
var x = 2;
console.log(x); //2
}
console.log(x);// 2
结果输出 1 2 2,是因为javascript是函数级作用域,在javascript中es6之前都不存在块级作用域,也就是说对于if语句,它不会创建新的作用域,只有函数才会创建新的作用域。
变量提升 函数提升
javascript中定义的变量或函数会被放在当前作用域的最顶端。
值得注意的是,提升的仅仅是变量的名字,所赋的值还是没有提升的。
函数我们一般有两种写法:
1 函数表达式(提升失败)
function myTest(){
foo();
var foo =function foo(){
alert("我来自 foo");
}
}
myTest();
2 函数声明(提升成功)
function myTest(){
foo();
function foo(){
alert("我来自 foo");
}
}
myTest();
值得注意的是只有函数声明的方式才会连函数体一起提升,而函数表达式中只会提升函数名,函数体只有在执行大赋值语句中才会被赋值。