執行環境 (Execution Context)

  • JavaScript 一次只能做一件事情,他會依據 執行環境 (Execution Context) 來一一執行工作內容
  • 函式在全域環境下(global context),然後這個全域環境下可以登記其他函式,然後每一段執行環境下會有屬於他的變數以及物件,如果找不到該執行環境的變數或物件,則會向外層尋找。
  • 地方我們得到了三個執行環境(Execution Context),其中一個是 (global context),另外兩個則是在 global 下的 doMorningWork 內。
function doMorningWork() {
  // 從此 function 的大括號是另一個執行環境
  var mom = "老媽";
  var breakfast = "麵包";

  function sayHi() {
    // 說早安執行環境
    return 'hi ' + mom;
  }

  function eatBreakfast() {
    // 吃早餐執行環境
    return '吃 ' + breakfast;
  }

  console.log('早安,' + sayHi() + ', ' + eatBreakfast());
}

doMorningWork();   // 執行


###
早安,hi 老媽, 吃 麵包

執行堆疊

  • 在這個故事中也可以說明 JavaScript 的執行堆疊,一開始會先進入 global 執行環境,接下來再進入內層的環境,執行完的堆疊就會被釋放掉 (function 內的 return 即是完成),然後逐步地完成所有堆疊,最後將控制權交還給 Global。

  • JavaScript 由外而內執行,執行完才會進行下一個動作

  • 如果其中一個環境卡住,那麼 JavaScript 就會掛掉(小明想不通)

  • 另外,變數的作用域也與此有很大的關係,

作用域

  • 變數分為全域與區域變數,差異點在於宣告 (var) 的方式
  • 函式以外宣告的稱為全域
  • 函式之內宣告的稱為區域

在函數外宣告的變數則是具有全域性(或是包含全域物件之內),在瀏覽器下的全域物件是window,有以下方式所產生的變數都會在window內,所以無論你的變數或函式是否要使用全域,都盡可能地去宣告它。

// 在函示外宣告
var mom = '老媽';

// 沒有使用 var
mom = '老媽';

(function () {
  // 或是在函式內,但沒有使用 var
  mom = '老媽';
})();

變數與他的作用域

每個變數在宣告時,都只會在執行環境內建立記憶體,這個就是他的作用域,單如果此作用域內沒有可用的變數時,他則會參照外圍

外層 doMorningWork(); 具有

  • mom的變數
    • 內層 sayHi(); 可以使用mom這個變數,讓小明可以跟媽媽說早安
  • 另一個函式就無法取用mom這個變數
function doMorningWork() {
  var mom = "老媽";

  function sayHi() {
      var greeting = 'hi';
    return greeting + ' ' + mom;
  }
  console.log(sayHi());
}
doMorningW

變數與記憶體關係

使用 var 宣告一個變數時,記憶體會先準備一個空間給予此變數,所以在實際運行前調用此變數並不會出現錯誤,只會出現

undefined(已經有記憶體空間,但沒有值)。

console.log(mom); // mom is not defined
mom = '老媽';
console.log(mom); // undefined
var mom = '老媽';

宣告與不宣告

全域物件裡的一個無法變更 (non-configurable) 的屬性, 而未宣告的變數則是可變更的 (configurable)

var mom1 = "老媽1";
mom2 = "老媽2"; 

(function () {
  mom3 = "老媽3"; 
})();

delete mom1;
delete mom2;
delete mom3;

console.log(window.mom1);  // 僅剩此有值
console.log(window.mom2);
console.log(window.mom3);

results matching ""

    No results matching ""