JavaScript 執行機制 —— 變量提高

1、執行順序

先看一段平常開發中遇到的代碼(片斷1)瀏覽器

display()
console.log(name)
var name = "掘金"
function display() {
  console.log("平常學習產出")
}
複製代碼

經過控制檯輸出,如圖:
bash

若是將上面的第三行代碼刪除(片斷1)

display()
console.log(name)(下面打印的name1,只改了個名稱)
function display() {
  console.log("平常學習產出")
}
複製代碼

再執行上面的代碼,結果以下:函數

從上面兩段代碼能夠看出:學習

  • 在執行的過程當中,未申明的變量,會出現報錯;
  • 在變量定義以前使用,結果爲undefined;
  • 直接申明函數,在以前調用它,正常執行。

若是變量聲明用 let、const 關鍵字會出現啥狀況呢
若是用google瀏覽器二次執行片斷1(刷新)又會遇到啥狀況
this

2、變量提高

JavaScript 調用一個函數或者使用一個變量,不得不在編譯的過程當中先進行聲明賦值,下面是變量的聲明和賦值google

var name = "掘金"
複製代碼

這段代碼能夠分紅兩部分spa

var name   // 聲明部分
name = "掘金" // 賦值部分
複製代碼

以下圖所示:3d

函數的聲明和賦值code

function display() {
  console.log("平常學習產出")
}
var display = function() {
  console.log("平常學習產出")
}
複製代碼

圖解以下:cdn

變量提高函數及變量的聲明都將被提高到函數的最頂部。

  • 代碼在執行的過程當中,會把聲明的部分提高到代碼開頭,若是有賦值就不用賦值,沒有就設置默認值undefined
  • 原有的var關鍵字會移除,例子中 name = "掘金",它變量提高的過程當中就剔除var字段

3、執行原理

變量提高並不是從物理層面移動到代碼的最前面,實際上變量和函數聲明在代碼中的位置是不變的,JavaScript代碼是在內存中執行的,因此時常都說JavaScript代碼先編譯,後執行;這個過程會出現兩個模塊:執行上下文可執行代碼這兩個定義常常都會在各類博客和項目中說起到,後續諸如 this、變量、對象都與之相關
如圖:

一、編譯階段

從上圖執行流程細化過程當中,編譯階段代碼能夠分紅兩部分:

  • 第一部分:變量提高的代碼
var name = undefined
function display() {
  console.log("平常學習產出")
}
複製代碼
  • 第二部分:執行的代碼
display()
console.log(name)
name = "掘金"
複製代碼

二、執行階段

  • 當執行到display() 函數時,JavaScript引擎在環境變量中查找函數,因爲變量環境中存在該函數引用,因此JavaScript引擎執行該函數代碼塊,並輸出結果;
  • 接下來控制檯輸出name,環境變量中name的默認值是undefined,因此這時候輸出爲undefined;
  • 最後「掘金」賦值給環境變量中name字段,這時候name="掘金"

若是出現相同的函數聲明,執行最後一個函數,前面的函數會被覆蓋

若是是下面的狀況又如何:

console.log(display)
display()
var display = function() {
    console.log("學習要有產出")
}
複製代碼

4、總結

  • JavaScript執行過程當中要作變量提高,緣由是JavaScript代碼需先進行編譯;
  • 在編譯階段,變量和函數都存放在內存的環境變量中,默認值設置爲undefined,在代碼執行階段,直接調用變量環境中相應的變量和函數;
  • 若是相同的函數,環境變量會覆蓋前面全部的相同命名的函數,保留最終定義的那個。
相關文章
相關標籤/搜索