能在宣告变数、函式、物件与其他型别前先进行使用,但是初始化并不会被提升。
因为 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的,但是当你尝试先宣告再使用时,会出现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 的程序教学笔记
搞定了架构和想法後,再来就要搞定画面的呈现。自己刻画面固然可以随心所欲呈现自己想要的样子与控制自己只...
之前范例执行结束如上所示,倘若我们希望点选学生即展开该学生成绩怎麽做? Grid 显示 Detai...
很开心来到了铁人赛的最後一天,相较於去年的铁人赛,今年的铁人赛比较水深火热一点,因为那万恶的mach...
我们透过 Docker Compose 建立环境,并在其上建立Django REST Framewo...
今天要来介绍Composite Pattern,是属於Structural Design Pat...