先说一下预解析的感念:
在当前作用域下,js在运行之前都会去进行预解析,预解析会把带有var 和 function 的关键字声明,并在内存中安排好,进行预解析,然后再逐行读取代码(注意预解析只会发生在var 定义的变量和function上)。
例一:
// An highlighted block
console.log(a) //undefined
var a = 1;
说明:预解析找到var 定义的变量a,将a赋值给undefined,逐行读取代码时,这时console.log在前面,此时的a值时undefined,所以打印的是undefined,然后a才被赋值为1
例二:
// An highlighted block
var a = 1;
function fn(){
console.log(a); //undefined
var a = 3;
}
fn();
说明:因为预解析是先解析全局变量,然后在解析局部变量,全局变量var 定义的 a被赋值给undefined,然后局部变量里 var 定义的 a被赋值给undefined, 接下来进行逐行读取代码,全局变量的a 辅助为1,局部变量console.log打印a,此时的a 是undefined,然后a 被赋值为3. 所以打印结果为undefined.
例三:
// An highlighted block
var a = 1;
function fn(){
console.log(a); //1
a = 3;
}
fn();
说明:在局部作用域的预解析时,因为 a = 3并没有用var 来定义,所以他是全局变量,并且是不会被预解析的,所以找不到a,那么根据作用域链的规则,向外找a,这时找到了a = 1,
所以console.log(a)打印为1
注意:函数不管在什么地方声明 ,都会提升到最前面 .也就是说在js代码运行前 ,解析器会事先声明函数 ,然后在执行代码 ,所以会输出整个函数体的 !