什么是声明提前
javascript声明的变量和函数在所在的作用域始终是可见的,意味着变量在声明之前就可以被使用,这个特性就称的“声明提前”。
声明提前
先来一个简单的例子:1
2
3console.log(a);
var a = 123;
console.log(a);
编译器运行的结果分别是:undefined 123
这里为什么会是“undefined”而不是报出“a is not defined”的错误呢,原因就是因为javascript的声明提前,编译器在运行之前先将所有var的变量提升到最上面,但是变量对应的赋值不会跟着提升,相当于变成了:1
2
3
4var a;
console.log(a);
a = 123;
console.log(a);
讲到这里,大家是不是对声明提前有个初略的认识了,那么我们继续往下看一个例子:1
2
3
4
5console.log(a);
function a() {
console.log('this is function')
}
var a = 123;
编译器运行的结果是:a (){ console.log(‘this is function’) }
这是同时声明了变量和函数的情况,在javascript中,当函数和变量同时被声明提前,函数的优先级是高于var出来的变量,所以例子打印出来的是函数的表达式。如果不想打印出表达式,我们可以使用另外一种办法声明函数:1
2
3
4console.log(a);
var a = function() {
console.log('this is function')
}
这样编译器运行的结果就是: undefined
最后,我们来做一道面试题:1
2
3
4
5
6
7
8
9alert(a);
a();
var a = 3;
function a () {
alert(10);
}
alert(a);
a = 6;
a();
编译器运行的结果分别为:1
2
3
4function a () { alert(10); }
10
3
Uncaught TypeError: a is not a function // 报错
当我们遇到在代码中间var一个变量或者声明一个function的时候我们就得注意声明提前,先将声明的变量和函数提升到最前面,注意变量和函数之间的优先级,把题目解析为:1
2
3
4
5
6
7
8
9var a;
function a () {
alert(10);
} // 函数的优先级较高,我们可以看做覆盖掉var声明的
alert(a);
a();
a = 3;
alert(a);
a = 6;
解释完成后,我们就能准确的得到结果了!