JavaScript預解析:同名變量和函數、同名函數表達式和同名函數聲明


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

其它可借鑒的資料:https://www.jb51.net/article/90113.htm


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM