淺談JavaScript程式碼預解析 + 示例詳解

再次重逢的時間發表於2019-02-16

知識點

  • var 宣告的變數在預解析的時候只執行宣告,不會執行定義,預設值是 undefined
  • function 宣告的函式在預解析的時候會提前宣告並且會同時定義。
  • 變數名重複宣告無效
  • 預解析過得程式碼不會再執行階段執行

示例一

console.log(a);  // 列印函式a函式體(function a() { console.log(`a`) })

var a = 10;

console.log(a);  // 10

function a() { console.log(`a`) }

console.log(a);  // 10
預解析過程
  1. 首先預解析到有變數 a 存在,因此記錄下 a 這個名字,和其值 undefined
  2. 接著預解析到有函式 a 宣告,記錄下函式名 a
  3. 但是發現已經記錄了一個 a ,因此該操作無效,將函式體與 a 這個名字相關聯
  4. 解析完畢
預解析過程程式碼
  1. a = undefined
  2. a = function () { console.log(`a`) }
預解析結果
  1. a = function () { console.log(`a`) }
執行過程
  1. 列印變數 a 的值 function a() { console.log(`a`) }
  2. 變數 a 賦值為10,將原來關聯的函式覆蓋
  3. 列印變數 a 的值 10
  4. 列印變數 a 的值 10
  5. 執行完畢
執行過程程式碼
  1. console.log(a)
  2. a = 10
  3. console.log(a)
  4. console.log(a)

示例二

console.log(fn)  // 函式fn函式體(function fn() { console.log(2) })

function fn() { console.log(1) }

console.log(fn)  // 函式fn函式體(function fn() { console.log(2) })

var fn = 10    

console.log(fn)  // 10

function fn() { console.log(2) }   

console.log(fn)  // 10
預解析過程
  1. 首先預解析到有函式 fn 宣告,因此記錄 fn 這個名字,並關聯其函式體
  2. 接著預解析到變數 fn 宣告,記錄下變數名 fn
  3. 但是發現已經記錄了一個 fn ,因此該操作無效
  4. 接著預解析到有函式 fn 宣告,因此記錄 fn 這個名字
  5. 但是發現已經記錄了一個 fn ,因此該操作無效,接著關聯其函式體
  6. 解析完畢
預解析過程程式碼
  1. fn = function () { console.log(1) }
  2. fn = function () { console.log(2) }
預解析結果
  1. fn = function () { console.log(2) }
執行過程
  1. 列印變數 fn 的值 function fn() { console.log(2) }
  2. 列印變數 fn 的值 function fn() { console.log(2) }
  3. 變數 fn 賦值為10,將原來關聯的函式覆蓋
  4. 列印變數 fn 的值 10
  5. 列印變數 fn 的值 10
  6. 執行完畢
執行過程程式碼
  1. console.log(fn)
  2. console.log(fn)
  3. fn = 10
  4. console.log(fn)
  5. console.log(fn)

相關文章