JavaScript Hoisting (提升)

Hoisting

能在宣告变数、函式、物件与其他型别前先进行使用,但是初始化并不会被提升。
因为 JavaScript 分成编译跟执行两个阶段,在编译阶段会把宣告的东西存在记忆体中,而等到执行阶段就可以拿出来用了。
EX:

//函式
SayHi("Ivy"); //Hi, Ivy.

function SayHI(name) {
  console.log("Hi, " + name + "." );
  
  //变数
  console.log(a); //undefined
  var a = 1234;
}

刚刚上面的变数a,因为只有宣告会被提升,因此结果出来并不是 ReferenceError: a is not defined,而赋值的部分没有,所以才会出现 undefined,因为所有变数一开始都会被预设为 undefined。

Hoisting 并不是文件规范的词汇

因为 JavaScript engine 执行时,事实上没有东西真正被 「Hoist」,所以我们只能说「想像」会比较好理解。
所以刚刚上面的变数a的范例可以想像成:

var a;
console.log(a);
a=1234;

所以会出现undified就不觉得奇怪了。

**小提醒: 如果有变数与函式是同名的宣告,则在优先权上函式的提升会高於变数:
请看下面范例。
EX:

console.log(a); // ƒ a(){return 'Good morning!';}
var a = "Ivy";

function a(){
return 'Good morning!';
}

let 与 const 没有 hoisting?

事实上, let 与 const 是有 hoisting的,但是当你尝试先宣告再使用时,会出现TDZ error。
他们不会初始化为 undefined,而且在赋值之前试图取值会发生错误(temporal dead zone)。

These variable declarations only become initialized when they are evaluated during runtime. The >time between these variables being declared and being evaluated is referred to as the temporal >dead zone. If you try to access these variables within this dead zone, you will get the >reference error above.

这强迫你不要在宣告前使用他们。

而TDZ error 是为了 const, 因为const 不能被重新赋值(记得所有变数在预设状态会被设为undifined)
而let是与const一起推出的,let 也是用这样的模式。

想进一步了解可以去看这篇文章,我觉得写得蛮详细的
Ashe Li [day21] YDKJS (Scope) : Hoisting ? let 会 Hoist 吗 ?

参考资料:
How Hoisting Works With ‘let’ and ‘const’ in Javascript
MDN 提升(Hoisting)
Huli 我知道你懂 hoisting,可是你了解到多深?
Shubo 的程序教学笔记


<<:  Day10 iPhone捷径-位置Part2

>>:  10. CI x Github Action

DAY6 - 挑选一套自己喜欢的UI框架

搞定了架构和想法後,再来就要搞定画面的呈现。自己刻画面固然可以随心所欲呈现自己想要的样子与控制自己只...

Grid 展开 Detail - day18

之前范例执行结束如上所示,倘若我们希望点选学生即展开该学生成绩怎麽做? Grid 显示 Detai...

[Lesson30] 结语

很开心来到了铁人赛的最後一天,相较於去年的铁人赛,今年的铁人赛比较水深火热一点,因为那万恶的mach...

[Day12] - Django REST Framework 专案建立

我们透过 Docker Compose 建立环境,并在其上建立Django REST Framewo...

IT铁人DAY 13-Composite 组合模式

  今天要来介绍Composite Pattern,是属於Structural Design Pat...