1. 程式人生 > >JS變數提升和函式提升

JS變數提升和函式提升

1.變數提升

  在ES6之前,我們宣告一個變數需要用到var關鍵字,用var來宣告的變數就存在變數提升的特性。

   

  上述程式碼粗略來講解,在上述程式碼中存在全域性作用域和函式作用域,在兩個作用域中都聲明瞭變數a。在fn函式執行console.log(a)的時候,先會在自身所處在的函式作用域中找到變數a,

如果沒有找到,就會去全域性作用域中找。

  在fn函式作用域中我們可以看到a變數宣告並賦值了,但是它處於console.log(a)語句的下方,按照正常的邏輯,它不應該找到的是外層定義的a嗎?但是結果恰恰相反。

  程式碼執行流程:

    我們可以根據位置來把程式碼分為全域性程式碼和函式(區域性)程式碼。在執行全域性程式碼前,首先將window新增為全域性執行上下文,之後對全域性資料做預處理工作:

      (1)找到var關鍵宣告的變數,賦值為undefined,且新增為window的屬性。=>變數提升

      (2)將function宣告的變數賦值fun(),新增為window屬性。=>函式提升

      (3)this =>賦值window

  在預處理結束後,開始執行全域性程式碼。

  函式程式碼執行流程也和上述大同小異,這裡涉及到執行上下文,就不細講了,後續會補充。

  所以我們可以這樣理解這行程式碼

  

 

 

   最後的結果自然就是undefined。這就是js存在的變數提升。

 

2.函式提升

  函式提升和變數提升的原理一樣,區別就是在於,函式提升已經建立好了函式物件,而變數提升賦值為undefined,可以理解為變數宣告提升。

   

 

 

   

 

 

 

 

 

 

 

3.拓展

  (1)var fn = function(){}和function fn(){}的區別:前者為變數提升,後者為函式提升。

    

 

 

 

 

    

 

 

   如果是用變數提升來宣告函式,如果在此前呼叫該函式,此時的函式物件並沒有建立,變數fn2賦值為undefined,所以瀏覽器不能識別,把它當做函式來呼叫,所以最後報錯。

 

  (2)在js中,函式是第一公民

    被覆蓋的不是函式fn,而是var fn =3;

   

  結果:

  

 

 

 

    

 

&n