Skip to content
On this page

Hoisting 提升

對於過去的印象,程式是一行一行向下執行,但 Javascript 會在程式執行之前,將 函式宣告變數宣告 先放進 記憶體裡面,這樣是為了讓程式在宣告 函式變數 之前,就可以使用,不會發生 錯誤;實質上宣告會被提升到最前面,但 賦值 還是在原位。

簡單說

hoisting 提升 就是,程式執行之前 Javascript 會將 宣告 放到所有 程式 之前。

  • 宣告 會提升,賦值 沒有
  • 函式變數 宣告都會提升
  • 函式參數函式 內部也是一種宣告

宣告提升

執行未宣告的變數 將會發生錯誤

js
console.log(a)
// Uncaught ReferenceError: a is not defined

宣告之前執行 宣告位置提升,但賦值 位置不變

js
console.log(a)
var a = 1
// undefined

// --- 程式解讀 ---
var a // hoisting
console.log(a)
a = 1

WARNING

hoisting 提升的是 宣告,而不是 初始化 (賦值) 。

宣告函式前執行

js
sayHello()

function sayHello() {
  console.log('Hello')
}

// Hello

提升優先順序

函數參數宣告變數

函式參數 默認的行為,是會在 函式 中,宣告且賦值,再接續執行後續程式。

js
function sayHello(name) {
  console.log(`Hello ${name}`)

  var name = 'In side'
}

sayHello('Out side') // Hello Out side

hoisting 之後

js
function sayHello(name) {
  var name = 'Out side' // 呼叫函式
  var name // 提升

  console.log(`Hello ${name}`)

  name = 'In side'
}

sayHello('Out side') // Hello Out side

函式與變數

函式的宣告順序高於 變數

js
console.log(a)

var a = 1
function a() {}

// ƒ a() {}

let 與 const

letconst 是存在區域的 區域變數,它們一樣會在區域內 hoisting 提升 置頂,只是在宣告之前,都會讓其 封閉作用 ,存在 時間死區 (Temporal Dead Zone)。在宣告之前就操作,就會出現 ReferenceError

js
console.log(aa)
let aa
// Uncaught ReferenceError: abc is not defined

console.log(bb)
const bb
// Uncaught SyntaxError: Missing initializer in const declaration

變數宣告

letconst嚴格 在宣告前都無法使用,會 Errorvar 在宣告前使用,只會 undefined,而不會 Error,這也就是自 ES6 後,希望開發使用 let const 為宣告方式

Reference