預解析的含義:在寫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