原本以為自己已經懂 Hoisting(提升),但今天再次接觸到卻又有「誒!原來是這樣!」的感覺,所以來整理筆記啦!
讓部分變數在執行到那行程式碼進行宣告之前,就得以使用。
在程式碼執行前,JS engine 會先偵測變數宣告,然後每個變數會在 Variable Environment Object 被創造出新的 property,接著才開始執行程式碼。
var x = 1;
console.log(window);
// Window is the global object of JavaScript in the browser.
// 當我們呼叫 window 時,可以在裡面找到 property x,且 value 為 1
-- | 會被 Hoist 嗎? | 被 Hoist 後的值
------------- | -------------
function declaration | ✅ | 原程式碼var
variables | ✅ | undefinedlet
& const
variables | ⚠️ 理論上YES,但會發生error,可以當成NO | error: uninitialized、TDZ
function expressions & arrows | 根據使用var
、let
、const
哪個進行宣告 | 同左
⬇️ Variables TEST
console.log(x); // undefined (留意undefined是falsy值,如果這狀況發生在if的條件裡,就容易出錯
console.log(y); // Uncaught ReferenceError: Cannot access 'y' before initialization
console.log(z); // Uncaught ReferenceError: Cannot access 'z' before initialization
console.log(x === window.x); // true (這個值存在於windows這個object裡
console.log(y === window.y); // false
console.log(z === window.z); // false
var x = 1;
let y = 2;
const z = 3;
⬇️ Functions TEST
console.log(addDeclaration(1, 6)); // 7
console.log(addExpressionVar(1, 6));
// Uncaught TypeError: addExpressionVar is not a function
console.log(addExpression(1, 6));
// Uncaught ReferenceError: Cannot access 'addExpression' before initialization
console.log(addArrow(1, 6));
// Uncaught ReferenceError: Cannot access 'addArrow' before initialization
function addDeclaration(a, b) {
return a + b;
};
var addExpressionVar = function (a, b) {
return a + b;
};
let addExpression = function (a, b) {
return a + b;
};
const addArrow = (a, b) => a + b;
TDZ:Temporal Dead Zone,ES6 才開始有,為
let
const
在該Scope宣告變數之前的區域,變數還不能被使用,若使用會出現警告Uncaught ReferenceError: Cannot access 'x' before initialization
const
的特性,如果const
同var
都會被 hoist 成 undefined,之後跑到那行程式碼才 reassign 成原本的值,就違反了const
不能 reassign 的特性。建議在每個 Scope 的最上方就宣告 variables 和 functions,然後才使用它們!
The Complete JavaScript Course 2022: From Zero to Expert! Unit 94 & 95
以上是今天的分享,謝謝看完的你!