[Day 18] JS - 变数提升Hoisting

前言

今天又要来介绍新的基础观念啦,在认识Hoisting之前,只单纯知道宣告变数的方式,也没有在乎它放在程序哪个段落会不会有影响。
在 JavaScript 中,不管你在函数中的哪一行用 var 宣告变数,一律视为在函数的第一行宣告。虽然单纯看来是被移动到程序的区块顶端,但要注意的是,变数和函数的宣告会在编译阶段就被放入记忆体,这样做的优点,可以在程序码宣告该函式之前使用它。

学习资源分享

  1. 彭彭 - JavaScript 网页前端工程入门:Hoisting 宣告提升,这次一样推荐彭彭老师的前端工程入门,讲解的很慢、很清楚,对当时第一次听的我来说,可以快速抓住要点。
  2. MDN - Hoisting,MDN 也有 Hoisting 范例说明,能够快速理解 Hoisting 是什麽。

举例说明:

  • var x=1之前写上console,x印出来会是什麽? 会印出undefined
  • 完全同等var x=undefined; console.log(x); x=1;
  • 如果直接宣告console.log(y)会出现referenceError:y is not defined(因为从来都没有直接用var 去宣告过y)

  console.log(x);
    var x = 1;
  • 完全同等
 var x = undefined
    console.log(x);
    x = 1;
  • 没有宣告过的变数,会出现错误

以上范例为基本对於提升的解释,虽然学程序的时候我们就学到了一个观念,「程序是一行一行跑」,但因为hoisting,即便在console.log之後,才宣告var x,也会因为「提升」,而到了最上面。

那除了宣告变数会提升之外,函式呢?

  • 函式的宣告也会提升
    • 优先权比较高
 console.log(x) //[Function: x]
    var x
    function x() { }

也可参考此范例,更清楚了解函式的优先提升

  • 上述宣告变数使用var,而在 ES6 里多了两个宣告变数:let 及const。

let 跟 const 与 hoisting

console.log(x);// ReferenceError: x is not defined
    let x

以为这样let就没有提升吗?直到看到Huli老师文章范例

var a = 10
function test(){
  console.log(a)
  let a;   //这里也用let宣告a
}
test()

Huli:
如果 let 真的没有 hoisting 的话,答案应该会输出10,因为 log 那一行会存取到外面的var a = 10的这个变数
答案却是:ReferenceError: a is not defined
意思就是,它的确提升了,只是提升後的行为跟 var 比较不一样。

  • 与 var 的差别在於提升之後,var 宣告的变数会被初始化为 undefined,而 let 与 const 的宣告不会被初始化为 undefined。
  • 在「提升之後」以及「赋值之前」这段「期间」,如果你存取它就会抛出错误,而这段期间就称做是 TDZ(Temporal Dead Zone),它是一个为了解释 let 与 const 的 hoisting 行为所提出的一个名词。

重复宣告

函式和变数同名,则函式会优先

同时多个函式同名

最後一个 test 会覆写前面的宣告,因此得到 3。


    test(); // 3

    function test() {
      console.log(1);
    }

    function test() {
      console.log(2);
    }

    function test() {
      console.log(3);
    }

参考资料
我知道你懂 hoisting,可是你了解到多深?
JS 额外补充:hoisting 变数提升
你懂 JavaScript 吗?#13 拉升(Hoisting)


<<:  Day 3 - 系统面临哪些威胁?

>>:  CSS微动画 - 了解Animation并做出更多效果吧!

【Side Project】 做Side Project前的准备

曾有一个刚大学毕业的朋友(以下称朋友)问我关於求职的问题 朋友: 我非本科系毕业,又没经验要怎麽找软...

Date & time

上一篇在实作 EtaResponseMapper 的时候我们用了 Java 8 开始有的 Insta...

危害指标(Indicators of Compromise:IoC)

这个问题是根据痛苦金字塔设计的。它不是一个行业标准,但它提供了一个很好的基础,以评估在威胁源中提供的...

D-30-安装 vscode ? dotnet sdk

离实习结束还有30天 实习生小光第一天到新公司实习,什麽都不懂的他到底会遇到什麽事情呢,让大家想想第...

[Day8]C# 鸡础观念- 如果没有如果,只有太多的如果switch陈述式

你是否曾经内心充满各种如果呢? 如果....我就...., 一组if已经满足不了你时, 那该如何是好...