JavaScript 是如何運行

直譯式語言

JS 是直譯式語言,不須先指定型別,也就是動態的語言,例如:JavaScript、Python、Ruby 等等。
也被稱作高階語言(High-level programming language),就是被高度封裝了的程式語言,離電腦的底層比較遠,跟編譯式語言對比起來,編譯式語言就是相對低階的

編譯式 vs. 直譯式

/ 直譯式語言 編譯式語言
除錯速度
執行速度
開發速度
可獨立執行 否,需依賴執行環境

直譯式轉換過程

我們可以到Esprima查看這個過程

語法單元化

將詞彙解析,在這並不會知道甚麼是變數,只會辨識一些 ketword 或是標點符號

抽象結構數

到這邊才知道我們正在定義一個變數,但還沒執行,要到代碼生成之後才執行,但因執行環境不同生成過程並不一樣

LHS, RHS

LHS(left-hand side)

LHS 用來賦予值到左邊的變數上

此範例將 1 賦予到左邊的變數上

let num = 1;

當賦予發生錯誤Uncaught SyntaxError: Invalid left-hand side in assignment分配中的左邊無效

RHS(right-hand side)

RHS 取值來自於右側的變數上

此範例就是將會從右側取值,記得要先定義 num 變數,不然會發生錯誤

console.log(num);

語法作用域

JS 屬於語法作用域也稱為靜態作用域,有靜態當然也有動態來看看差別

/ 靜態作用域 動態作用域
差別 變數作用域在語法解析時,就已經確定作用域,且不會再改變 變數的作用域再函式調用時才決定

作用域

JS 在函式中會先尋找該函式裡是否由此變數名稱的變數,若沒有就會往外查找,再找不到就會出現錯誤

在此舉例,fun1 會先尋找 fun1 裡是否有 num 變數,找不到所以他向全域尋找,所以會輸出 1。

var num = 1;
function fun1() {
console.log(num); // 語法作用域: 1
// 如果是動態作用輸出 2
}
function fun2() {
var num = 2;
fun1();
}
fun2();

執行環境

這邊來講講執行環境與執行堆疊

函式執行環境,要在 call 函式之後才會出現

function callMe(){
...
}

全域執行環境在一開啟時就會執行

執行堆疊

JS 執行是一層一層堆疊,離開時也是一層一層離開

依照下圖範例,執行環境依照,全域環境->fun2 函式->fun1 函式,的方式堆疊,
再由 fun1 先離開->fun2 函式離開,然後回到全域環境