预解析的含义:在写js代码调用函数的时候,无论你是在调用位置的前面或者后面声明函数,都可以正常调用,
原因是,JavaScript碰到script标签,会将var变量(注意是var)声明和函数声明(注意是声明)提升到当前作用域最前面。
预解析结论:变量的提升,指的是声明的提升,赋值(初始化)并不会提升
看一些例子:
例1:
//例1 console.log(num); var num = 2; //上述代码:解析过程 var num; //第一步:预解析 //执行过程 console.log(num); //第二步:打印结果-->undefined num = 2; //第三步:赋值
说明:变量声明提升,赋值不提升
例2:
//例2: var num = 2; var num; console.log(num); //上述代码:解析过程 var num; //第一步:预解析 var num; //第二步:预解析 num = 2; //第三步:赋值 console.log(num); //第四步:打印结果-->2
结果不是undefined?因为var 变量是会提升的,提前预解析了,然后又赋值了,所以结果为2。
扩展-1:
//扩展-1 function f() {} var f; console.log(f); //上述代码:解析过程 function f() {} //第一步:预解析整个函数 var f; //第二步:预解析 console.log(f); //第三步:打印结果-->function f() {}
按理说,这里应该是undefined,结果不是
原因:预解析时,当变量和函数同名时,优先留下函数的值(不管谁前或后,函数优先级更高)
扩展-2:
//扩展-2 function f() { console.log(num); // undefined } var num;
这里函数里面能访问到num,证明变量的声明会在函数声明之前
这个问题是个人的理解,有疑问的读者也可以去查些资料。
例3:
//例3 var f = function() { console.log(1) } function f() { console.log(2) } f(); //上述代码:解析过程 var f; //第一步:预解析 function f() { console.log(2)} //第二步:预解析--f整个函数 f = function() { console.log(1)}//第三步:f赋值整个函数 f(); //第四步:执行函数f-->输出1
例4
//例4 f(); var f = function() { console.log(1) } function f() { console.log(2) } f(); //上述代码:解析过程 var f; //第一步:预解析 function f() { console.log(2)} //第二步:预解析--f整个函数 f(); //第三步:执行f函数-->输出2 f = function() { console.log(1)}//第四步:f赋值整个函数 f(); //第五步:执行f函数-->输出1
这个例子和前一个只是函数调用位置发生了改变,结果也变了
例5:
//例5 f(); var f = function(){ console.log('k') } //上述代码:解析过程 var f; //第一步:预解析 f(); //第二步:执行f函数,报错 f = function(){ console.log('k')} //第三步:f赋值整个函数
原因:调用一个未赋值的函数,当然会报错,
注意:这个例子,将函数表达式换成函数声明就不会报错了,
因为函数声明会提升,这也是我们常用函数声明的一个原因,可以在任何位置调用。
例6:
//例6 var num = 2; function f() { num = 1; console.log(num) return var num = 3; } f(); console.log(num); //上述代码:解析过程 var num; //第一步:预解析 function f() { //第二步:预解析--f整个函数 //解析过程 var num; //此处提升的变量是return后面的 num = 1; //num赋值 console.log(num) //执行时,会输出1 return //后面的代码不会执行 num = 3; } num = 2; //第三步:num赋值 f(); //第四步:执行f函数-->输出1 console.log(num); //第五步:输出结果-->2
说明:return后面的语句虽然不会执行,但是变量还是会提升,所以f函数执行时,会输出1
例7:
//例7 console.log(num); //报错 num = 2;
只有var会提升,隐式全局变量并不会提升,所以结果和例1不同,并不是undefined
本文引自:https://blog.csdn.net/m0_37897013/article/details/81701016