JavaScript Hoisting 是指 JS 引擎在執行代碼之前,將 function、variables 或 class 的 declaration移動到其範圍頂部的過程
不論宣告變數的位置在哪,宣告的動作一律都會被「抬升」到函式的最頂端
// Hoisting 也會分配放進RAM
// let a;
// const z;
// var x = undefined;
// function hello() {...arguements...}
let a = 3;
const z = 6;
var x = 5;
hello();
function hello() {
console.log("hello");
}
Hoisting 的優點之一是,它允許我們在 code 中,declare function 之前使用這個 function(但要小心,這個功能只對 function declaration 有用)
sayHello(); // 可以在宣告之前呼叫 function
function sayHello() {
console.log("Hello!");
}
不適用於函式表達式function expression
sayHi(); // -> TypeError
let sayHi = function() {
console.log("Hi!");
};
// 函式表達式,必須在它被賦值後才能使用它
Hoisting 也適用於 variables ,因此我們可以在 declaration 或 initialization 之前在 code 中使用 variables
console.log(myVar); // 可以在宣告之前使用變數
var myVar = 10;
注意 JavaScript 只 hoist declaration
,而不是 initialization !只有宣告這個動作有 hoisting的特性,賦值的動作不會 hoisting。
也就是說,let x = 10; 這段程式碼只有let x會被放到程式碼頂部
Hoisting 發生時,使用 var
做 declaration 的 variable 會給定初始值 undefined
// 上述例子
console.log(myVar); // 可以在宣告之前使用變數,但由於他的初始化並沒有被提升,會在宣告之前undefined
var myVar = 10;
使用 let
, const
做 declaration 的 variable 並不會給定任何初始值
let myVar; // 沒有指定初始值
console.log(myVar); // -> undefined
const PI; // 沒有指定初始值
console.log(PI); // -> SyntaxError
使用 const 宣告陣列,不給定初始值,但需要注意的是,對於 const 來說,一旦給定了初始值,就不能再對其重新賦值
const colors = []; // 沒有指定初始值,但可以稍後賦值
colors.push("red");
console.log(colors); // -> ["red"]
let 可以 declare without initialization,且我們可以用 console.log()檢查 let 的變數值是 undefined
let myVar; // 宣告變數,但未初始化
console.log(myVar); // -> undefined
但這個 undefined 的 initialization 並不像 var 是發生在creation phase的hoisting階段發生的,而是在execution phase的階段。
// Hoisting
// let x;
console.log(x); // -> ReferenceError:Cannot access 'x' before initialization
let x;
let x; // execution phase階段才會去定義x = undefined
console.log(x);// -> x is undefined
下一篇文章學習進階的作用域、閉包。