iT邦幫忙

第 12 屆 iThome 鐵人賽

DAY 15
1
Modern Web

30天入門JavaScript系列 第 15

【Day 15】執行環境與呼叫堆疊

  • 分享至 

  • xImage
  •  


才15天就快不符合主題了,說好的入門呢




JavaScript被執行時會產生執行環境(execution Context),
執行環境分為全域環境區域環境

全域執行環境(全域環境)

預設的環境,在這環境宣告的變數為全域變數。


函式執行環境(區域環境)

在呼叫函式時會產生的執行環境,在區域環境下宣告的變數為區域變數,
函式執行完畢後該執行環境消滅。


...上面好像都是廢話,所以執行環境有甚麼用?

簡單說的話,一個執行環境會建立:

  1. 自己的區域變數
  2. 作用域鍊 (之後會講
  3. this值 (之後(略
  4. 相關的記憶體,在環境消滅後會釋放


JavaScript會用呼叫堆疊(call stack)來追蹤目前的執行環境,
最後建立的執行環境會被加在堆疊最上方,執行結束後會從堆疊取出。

例子:

var str = '全域變數';

function funcA() {
  var str = '區域變數A';
  funcB();
  console.log(str);
}

function funcB() {
  var str = '區域變數B';
  console.log(str);
}
funcA();

console.log(str);


用圖簡單解釋JS執行中call stack的變化(堆疊最上面的就是目前的執行環境)

  1. 建立全域環境,加入堆疊底部並建立全域變數str跟兩個函式
  2. 呼叫funcA,建立新的執行環境加入堆疊,建立區域變數str
  3. 呼叫funcB,建立新的執行環境加入堆疊,因為又是新的執行環境,再建立區域變數str


4. 印出str(區域變數B)後,執行環境消滅,相關的記憶體空間釋放
5. 回到funcA,印出str(區域變數A)後消滅,相關的記憶體空間釋放
6. 回到全域環境印出str(全域變數)

雖然宣告了三次變數str,但他們都是在不同執行環境下宣告的,所以彼此之間不影響。

如果有人覺得三個str之間不影響是因為他們是不同的函式,下面有個相同函式的範例

var a = 0;

function func() {
  var x = 1;
  x += a;

  if (a++ < 1) {
    func();
  }
  console.log('x等於' + x);
}

func();

執行結果:
https://ithelp.ithome.com.tw/upload/images/20200915/201298363fb0dHZFrl.png

這個函式會呼叫自己一次,呼叫自己後產生了新的執行環境,
造成即使是同一個函式,但執行環境不同不會互相影響


知道執行環境跟call stack對了解this的特性很重要,
鐵人賽後半場都是各種機制跟名詞解說,還請多指教


上一篇
【Day 14】陣列(三):陣列的回呼方法
下一篇
【Day 16】提升Hoisting
系列文
30天入門JavaScript30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言