每日挑战,从Javascript面试题目了解一些你可能忽略的概念 - Day4

tags: ItIron2021 Javascript

前言

昨天我们简单探讨了一下程序语言间常常出现的浮点数问题,同时也回味了一下火影忍者的某个角色,今天让我们继续藉由简单的面试题目来了解另一个你可能知道、却并不是那麽熟悉的概念吧!

本日题目与解释

请解释javascript中提升(hoist)的概念

老样子来个防雷图,思考结束後再往下滑吧!

thinking-bob

这同样也是一个js中基本的核心概念之一,用简单的一句话来说就是

在执行程序码之前(也就是编译阶段),把所有的宣告程序码(declarations)放入记忆体的位置中

这让我们有办法在函数/变数宣告前就先行使用该函数/变数,举个简单的例子

add(1,3) // 4

function add(a, b) {
  console.log(a + b)
}

在还没有运行到该行函数宣告时,我们就已经可以正确使用add函数了!
你可以想像上述的程序码变成以下的结构

function add(a, b) {
  console.log(a + b)
}

add(1,3) // 4

这种彷佛把函数/变数的宣告(declarations)移到该作用域的最上方的行为就称作提升,注意我用的词是彷佛,因为事实上程序码的实际位置并没有移动,只是先行被放到记忆体的位置造成了这样的结果。

若是要应付基本的问答,上述的说法可说是提升的最基础概念,应该足以你过关了,那麽试着面对以下的问题吧!

只有函数宣告会被提升吗?

照文章的铺陈,我想你也知道答案肯定是否定的。变数的宣告自然也会提升,我们同样看个简单的例子吧!

console.log(a)

var a = 3

若你觉得答案应该是3,那表示你需要继续往下看这篇文章?

上方的程序码可以用以下的结构理解,由於提升的关系,宣告的部分会先被放到记忆体位置(或是你想理解为移到该作用域的最上方也行!)

var a

console.log(a)

a = 3

提升的部分仅有宣告的行为,赋值是没有一并被提升的! 而我们知道宣告变数却不赋值的话,该变数的值会是undefined,最终印出undefined这样的结果!

OK! 现在你理解变数的宣告同时也会被提升,再看看下一个进阶一点的问题吧!

那let & const的宣告也会被提升吗?

这里开始就是个分歧点了,因为不少人会跟你说只有var宣告的变数会被提升。
首先先说结论,所有变数的宣告都会被提升,我们一样用个实例来证明吧!

function demo() {
  console.log(a)

  const a = 5
}

假设const/let宣告的变数并没有提升的行为,那麽我们在执行该函数时想必就会出现一个错误告诉我们a这个变数未被定义吧!也就是我们熟悉的那个错误讯息

Uncaught ReferenceError: a is not defined

但实际上去执行函数时你会发现跟你想像的并不一样

Uncaught ReferenceError: Cannot access 'a' before initialization

简单翻译就是你没办法在a变数尚未被赋值前就尝试使用该变数,综合我们之前的理解,这表示a变数确实也经过提升而被放到记忆体位置,只是let/const在被提升的行为与var并不相同,var宣告的变数被提升後,预设的行为就是给予undefined这个值作为初始化,相对的let/const并没有这样的初始化,且若是在被赋值前被尝试存取则采用丢出一个错误作为预设的处理方式,这样一个小小的区间(被赋值前被尝试存取)就被称为所谓的暂时性死区(Temporal Dead Zone),它听起来很潮但没什麽特别的,就仅是说明let/const被提升的行为有所不同的一个名词而已。

本日核心观念与总结

核心观念

提升(hoist)、变数宣告与赋值、暂时性死区

总结

  • 提升(hoist)就是把所有宣告都移到记忆体位置(或是作用域最上方)的行为
  • let & const 同样也会有提升的行为,仅是处理方式与var并不相同
  • 尝试在提升之後且赋值之前存取宣告的变数就会遇到暂时性死区(Temporal Dead Zone)

本文章同步发布於个人部落格,有兴趣的朋友也可以来逛逛~!

参考文章

今天的文章中较进阶的内容主要来自以下的文章,在我初学hoist的时候帮我了大忙

我知道你懂 hoisting,可是你了解到多深?


<<:  两种开发模式 (MVC, MVVM) 比较

>>:  Android学习笔记10

【资料结构】图的基本定义

一个图形具有两个集合的基本组成:G(V,E) V:表示顶点的集合 V(G1)={1,2,3,4} E...

#14-撒花~Button庆祝动态自己来!~ (JS)

敝人很常踩到诈骗网站,第一屏就是一个庆祝的小动画, 恭喜我中奖(好想中威力彩啊) 网页也很常有这种奖...

当SFC在Windows上无反应时如何解决?

“在过去的几年中,我一直在使用系统档案检查器(SFC)扫描和修复损坏档案,但是昨天,当我尝试执行sf...

[Day 04] C#轻松取得IV值&实作SHA256 - [C#]丰收款API必备前置作业(三)

先来复习一下: 昨天做的是取得Nonce及HashID的部分,今天就来讲要怎麽算IV值吧! 既然顺利...

抑制“重播HTTP cookie”攻击的最佳解决方案

-Cookie中的ASP.NET会话ID(来源:https://blog.httpwatch.co...