预解析
JavaScript代码是由浏览器中的JavaScript解析器来执行的,JavaScript解析器在运行JavaScript代码的时候会进行预解析,也就是提前对代码中的var变量声明和function函数声明进行解析,然后再去执行其他的代码。
为了使读者更好地理解,下面我们通过一段简单的代码来演示var关键字的预解析效果。
1 // 以下代码中的var num变量声明会进行预解析
2 console.log(num); // 输出结果:undefined
3 var num = 10;
4 // 以下代码由于不存在var num2,所以会报错
5 console.log(num2); // 报错,提示num2 is not defined(num2未定义)
在上述代码中,第2行在变量num声明前就访问了变量num,但却没有像第5行的num2一样报错,这是因为第3行代码中的var num会被预解析,相当于如下代码。
1 var num; // num的变量声明由于预解析而提升到前面
2 console.log(num); // 输出结果:undefined
3 num = 10;
由此可见,由于num的变量声明被预解析,所以console.log(num)不会报错,并且由于赋值操作num = 10不会被预解析,所以此时num的值为undefined。
同样,JavaScript中的函数也具有预解析的效果,示例代码如下。
1 fn();
2 function fn() {
3 console.log('fn');
4 }
在上述代码中,fn()函数调用的代码写在了函数声明的前面,但函数仍然可以正确调用,这是因为function函数声明操作也会被预解析。
需要注意的是,函数表达式不会被预解析,示例代码如下。
1 fun(); // 报错,提示fun is not a function(fun不是一个函数)
2 var fun = function() {
3 console.log('fn');
4 };
上述代码提示fun不是一个函数,这是因为var fun变量声明会被预解析,预解析后,fun的值为undefined,此时的fun还不是一个函数,所以无法调用,只有第2~4行代码执行后,才可以通过fun()来调用函数。