iT邦幫忙

第 11 屆 iThome 鐵人賽

DAY 3
1
自我挑戰組

JavaScript 試煉之旅系列 第 3

範疇(Scope)與提升(Hoisting)

  • 分享至 

  • twitterImage
  •  

在了解什麼是區塊範疇(block scope)以及函式範疇(function scope)之前,要先知道什麼是範疇(scope)。

範疇 (scope)

當我們在程式中引進變數時,我們必須給予這些變數一個安置它們的空間,如此一來我們才能在需要的時候將它們從那個空間中找出來使用。

而範疇(scope)就如同那個安置變數的空間。

函式範疇(function scope)

首先要學習的部分是函式範疇(function scope)。

函式範疇的定義是變數在 function(){...} 以外的地方為不可見,只有在函式中才可以使用那些被宣告的變數。

JavaScript在 ES6 之前是透過 var 宣告變數,所以會建立以函式為範疇的變數。

來看看這個測試例子:

function scope(){
  var a = 1;
  console.log(a);
  let b = 2;
  if(b > 1){
    console.log(a);
  }
}
scope();
console.log(a);

透過結果可以得知在 scope函式外的變數 a 無法得到內部變數 a 的值。
https://ithelp.ithome.com.tw/upload/images/20190919/20120099ivWbvYKpr7.png

再看看另外一個測試例子:

function scope(){
 let b = 2;
 if(b > 1){
   var a = 2;
   let c = 3;
  }
  console.log(a);
  console.log(c);
}
scope();

變數 a 是透過 var 宣告,因此變數屬於函式範疇,所以當寫在 if 條件句中,在外部也一樣可得到變數 a 的值 2

而變數 c 是透過 let 宣告,因此變數屬於區域範疇,所以當寫在 if 條件句中時,外部無法得到變數 c 的值 3

https://ithelp.ithome.com.tw/upload/images/20190919/20120099yjv2ZIeSTe.png

區域範疇 (block scope)

區域範疇的定義是變數在 {...} 以外的地方為不可見的,只有在 {...} 裡面才可以使用到那些被宣告的變數。

在ES6之後可以透過 letconst 兩種新的宣告方式,建立以區塊為範疇的變數。

來看看測試例子:

const foo = 3;
if(foo > 1) {
  let bar = foo * 2;
  console.log(bar);
}
console.log(bar); 

變數 bar 只在 {...} 的區塊有效,所以只在 if 條件句中可被讀取,而外部則讀取不到。

https://ithelp.ithome.com.tw/upload/images/20190919/201200991GN7yI9ejY.png

提升(hoisting)

JavaScript 環境建立時,會先將所有的變數、函數先存入記憶體空間(但這過程並不包含指定給變數的值及函式的執行內容,會在原地等待被執行)

因此,變數、函式會因為先行存入記憶體的緣故,而提升到程式碼的最上端。

而這個會將宣告的變數、函式從原本撰寫的位置提升到程式碼最上端的行為也稱為提升(hoisting)

先看看關於變數提升(hoisting)的例子:

console.log(a);
var a = 3;
console.log(a);

因為提升(hoisting),所以當透過 console.log(a) 時,會發現變數 a 的值為 undefined 而非 a is not defined

這代表 變數 a 已經被宣告,但還沒有被使用。

而第二個 console.log(a) 因為已經將值指定(assign)給變數 a ,所以可以得到值為 3

https://ithelp.ithome.com.tw/upload/images/20190919/20120099kjBuGyEz05.png

再看看關於函式提升(hoisting)的例子:

console.log(test());
function test() {
  return 2;
}

觀念同於變數,會先將函式名稱 test 存入記憶體空間中,所以即使是先執行 console.log(test()); 也依然可以得到值 2

https://ithelp.ithome.com.tw/upload/images/20190919/20120099p62qTJaRC2.png

關於範疇(Scope)與提升(Hoisting)的學習就告一段落囉

明天見~


上一篇
JavaScript 變數與資料型別
下一篇
JavaScript 陣列(Array)的特性與使用
系列文
JavaScript 試煉之旅30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言