iT邦幫忙

第 11 屆 iThome 鐵人賽

DAY 9
0
自我挑戰組

邁向 JavaScript 核心之路 系列 第 9

[Day 9] JavaScript 語法特性 - Hoisting

  • 分享至 

  • xImage
  •  
    console.log(a);
    var a = 1;

若要用一段程式碼來講 Hoisting,我想這段程式應該就會是Hoisting最佳的解釋了吧。

在剛學程式時,一直覺得這段 code 會顯示出 Uncaught ReferenceError: a is not defined,但實際運行上他卻只會出現 undefined ,直到後來才知道原來他就是所謂的 Hoisting

那 Hoisting 到底是什麼呢?

Hoisting 是指 一種把宣告提升到其區域內最頂端的內部行為,不過提升行為只針對宣告的部分,對於值的設定,並沒有跟著提升。

說了這麼多,還是用程式碼來示範給大家看吧!

    // 將變數宣告提升
    
    var x = 1;
    (function() {
      console.log(x); //undefined
      var x = 10;
    })();
    console.log(x); // 1;

實際上,程式的執行過程是

    var x = 1;
    (function() {
      var x;
      console.log(x); //undefined
      x = 10;
    })();
    console.log(x); // 1;

也就是上述的,將宣告提升到區域的最頂部。

各位是不是對於 Hoisting 好像有些了解但又不是很清楚呢?
沒關係,那我們就再來一段程式碼吧!

    var a = 1;
    function isHoisting() {
      if( !a ) {
          var a = 2;
      }
      console.log(a);
    })
    isHoisting();

聰明的同學們,你們認為 a 顯示出來的會是 A or B 呢?

(A) 1
(B) 2

沒錯,答案就是 (B) 哦,至於為什麼呢?

    // 實際程式執行過程
    var a = 1;
    function isHoisting() {
      var a;
      if( !a ) {
          a = 2;
      }
      console.log(a);
    })
    isHoisting();

就是因為 Hoisting 的緣故呢!

這邊補充一個小知識,有些人說 ES6 的 let 和 const 並沒有 Hoisting,
這個說法其實是有一些爭議的哦,
請看一下程式碼

    console.log(a);
    let a = 1;

若是拿這段程式碼執行,會出現 Uncaught ReferenceError: Cannot access 'a' before initialization 錯誤,這也就是為什麼他們會說 ES6 的 let 和 const 並沒有 Hoisting 的原因,但請看下方這段程式碼

    let a = 2;
    (function() {
      console.log(a);
      let a = 10;
    })();

這段程式碼能證明說 let 其實是有 Hoisting 的特性,但是其並無法操作,所以我們稱被提升至頂部的變數宣告
到使用該變數的這段,為死區( Dead Zone )。

我們換句話說,如果我們在死區內使用該變數,則 JavaScript 就會報錯。


今天身體一直不太舒服,打完這篇文章在廁所待了快一個小時,差點就來不及發佈了

參考資料:

Tommy - 深入 JavaScript 核心課程
TechBridge 技術共筆部落格 - 我知道你懂 hoisting,可是你了解到多深?


上一篇
[Day 8] JavaScript 語法特性 - Currying
下一篇
[Day 10] JavaScript 語法特性 - 嚴格模式
系列文
邁向 JavaScript 核心之路 30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言