全部 / 前端 / 技术 · 2022年9月6日 0

JavaScript 视觉化:提升

原文地址:https://dev.to/lydiahallie/javascript-visualized-hoisting-478h

提升是每个 JavaScript 开发者听过的众多词汇中的一个,因为你搜索令人恼火的问题时到最后 StackOverflow 的一个回答者告诉你那是因为提升导致的。所以,什么是提升?(FYI – 作用域会在另一篇文章中讲解,我想保持本篇文章短小且聚焦)。

如果你是 JavaScript 新手,可能经历过奇怪的行为。就是一些变量会随机的 undefined 、 抛出 ReferenceErrors 错误等等。提升经常被解释为相当于把变量或函数移动到文件头部。可实际并不是那样,即使表现行为看着像。

当 JavaScript 引擎拿到我们的脚本时,第一件事就是为我们代码中的数据分配内存。此时没有代码执行,就仅仅是简单的为执行准备好所有需要的东西。函数声明和变量的存储方式是不同的,函数是以对整个函数的引用来存储的。

gif7

而变量,有稍微的不同。ES6 引入了两个新的关键词来声明变量:letconst。通过 letconst 关键词声明的变量是未初始化的。

gif8

通过 var 关键字声明的变量默认值为 undefined

gif9

现在创建阶段完成,我们可以实际执行代码了。在我们声明任何函数或变量之前,一起看看在文件头部若有 3 个 console.log 语句会发生什么。

由于函数声明是对整个函数代码的引用,所以我们可以在创建它们之前调用🔥。

gif16

当我们在引用一个通过 var 声明的变量之前使用它时,只会返回它存储的默认值:undefined!可是,这有时会导致不可预期的的行为。在多数情况下,代表你是无意引用它(你可能并不希望它是 undefined)。

gif17

为了阻止意外引用一个 undefined 变量,就像使用通过 var 关键字定义的变量,无论何时我们使用一个未初始化的变量时 ReferenceError 错误将会被抛出。在实际声明变量之前的区域,称为:temporal dead zone 你不可以在变量(也包括 ES6 中的 class)初始化之前使用它。

gif18

当浏览器引擎执行过我们实际声明变量的代码时,内存中变量的值将会被我们声明它时赋值的值覆盖。

gif12

都结束了!快速总结下:

  • 当我们执行代码时,函数和变量被存储在执行上下的内存中,这称为提升。
  • 函数被存储为指向整个函数的代码引用中,通过 var 关键字声明的变量默认值为 undefined,而 letconst 关键字声明的变量则是未初始化。

我希望 hosisting 这块知识变得清晰一些了,特别是当我们执行代码,查找到底发生了什么时。像往常一样,不要担心如果它还没有带来很实际的意义。你若经常使用它,就会越来越适应它。