附上为何铁人赛文章会出现在这里的说明:2022 铁人赛|Day1 报名失败,还是要开赛吧!
背景脉络
原本以为自己已经懂 Hoisting(提升),但今天再次接触到却又有「诶!原来是这样!」的感觉,所以来整理笔记啦!
主题笔记
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
Hoisting 表
-- | 会被 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 initializationconsole.log(z); // Uncaught ReferenceError: Cannot access 'z' before initializationconsole.log(x === window.x); // true (这个值存在于windows这个object里console.log(y === window.y); // falseconsole.log(z === window.z); // falsevar x = 1;let y = 2;const z = 3;
⬇️ Functions TEST
console.log(addDeclaration(1, 6)); // 7console.log(addExpressionVar(1, 6)); // Uncaught TypeError: addExpressionVar is not a functionconsole.log(addExpression(1, 6)); // Uncaught ReferenceError: Cannot access 'addExpression' before initializationconsole.log(addArrow(1, 6)); // Uncaught ReferenceError: Cannot access 'addArrow' before initializationfunction 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?
TDZ:Temporal Dead Zone,ES6 才开始有,为
let
const
在该Scope宣告变数之前的区域,变数还不能被使用,若使用会出现警告Uncaught ReferenceError: Cannot access 'x' before initialization
为什么要有 TDZ?
可以帮助减少错误与侦错去符合const
的特性,如果const
同var
都会被 hoist 成 undefined,之后跑到那行程式码才 reassign 成原本的值,就违反了const
不能 reassign 的特性。心得
建议在每个 Scope 的最上方就宣告 variables 和 functions,然后才使用它们!
参考资料
The Complete JavaScript Course 2022: From Zero to Expert! Unit 94 & 95
以上是今天的分享,谢谢看完的你!