瘋狂的技術宅 前端先鋒 前端
翻譯:瘋狂的技術宅
做者:Paul Ryan
來源:alligator.io
正文共:2337 字
預計閱讀時間:7 分鐘ide
這是研究 JavaScript 內部工做方式的系列文章的第一篇。我會盡力使它變得有趣,而且不讓你感到厭煩,由於我知道這些東西有時會變得很是乏味!函數
想象一下,飛行員知道是飛機怎樣飛行的,而咱們天天運行 JavaScript 代碼,但知道它是如何運行嗎?動畫
先讓咱們敲出一些簡單的 JavaScript 代碼:線程
1const num = 3; 2 3function addOne(x) { 4 const result = x + 1; 5 return result; 6} 7 8const output = addOne(num);
上面的代碼沒什麼讓你值得興奮的,可是能夠很好地幫助咱們演示執行線程。翻譯
當執行 JavaScript 時,代碼會逐行(單線程)執行,所以在咱們的代碼中,要被執行的第一行是:3d
1const num = 3;
下一個問題是,執行這行代碼會發生什麼?num 存儲在哪裏?code
num 存儲在全局內存/執行上下文中,看起來像這樣:
blog
顯示如何執行第一行的動畫
而後進入下一行:ip
1function addOne(x) {
請務必注意,咱們在這裏聲明瞭一個函數,可是還不執行。所以,咱們將函數名稱與整個函數的值一塊兒存儲。
第二行如何執行
上面的 - f - 是整個函數的簡寫。
如今轉到下一行,有人可能認爲下一行是函數的主體,可是因爲咱們僅聲明函數而不是運行它,所以要運行的下一行是:
1const output = addOne(num);
與上面相似,咱們將標籤 output 發送到內存,但尚未值,由於咱們必須運行函數。
保存函數標籤
有趣的來了!接下來執行 addOne 函數。
當一個函數被執行時,它被添加到 call stack(調用棧)中。調用堆棧的底部老是有 global/main ,咱們如今將 addOne(3) 入棧。
調用堆棧
咱們還爲該函數建立一個 execution context (執行上下文)。函數中聲明的任何變量都會被添加到函數的執行上下文中。
將要添加的第一個變量是函數的參數,在本例中爲 x。
添加函數參數
如今,咱們移至下一行並將 result 存儲在 execution context 中。
存儲結果
在下一行,用了 return 關鍵字來標記函數的結束。咱們從調用棧中彈出 addOne(),並給 output 賦值爲4。
因此首先從 call stack 中彈出 addOne。
從調用棧彈出
如今是最後一步,將值 4 分配給 output 變量。
最後一步
就是這些了!我但願這可以演示 JavaScript 代碼是如何逐步執行的。在本文中提到了 call stack (調用棧)和 execution context(執行上下文),未來咱們將會更深刻地研究它們。
原文連接