原文地址:https://dev.to/lydiahallie/javascript-visualized-hoisting-478h
提升是每个 JavaScript 开发者听过的众多词汇中的一个,因为你搜索令人恼火的问题时到最后 StackOverflow 的一个回答者告诉你那是因为提升导致的。所以,什么是提升?(FYI – 作用域会在另一篇文章中讲解,我想保持本篇文章短小且聚焦)。
如果你是 JavaScript 新手,可能经历过奇怪的行为。就是一些变量会随机的 undefined
、 抛出 ReferenceErrors
错误等等。提升经常被解释为相当于把变量或函数移动到文件头部。可实际并不是那样,即使表现行为看着像。
当 JavaScript 引擎拿到我们的脚本时,第一件事就是为我们代码中的数据分配内存。此时没有代码执行,就仅仅是简单的为执行准备好所有需要的东西。函数声明和变量的存储方式是不同的,函数是以对整个函数的引用来存储的。
而变量,有稍微的不同。ES6 引入了两个新的关键词来声明变量:let
和 const
。通过 let
和 const
关键词声明的变量是未初始化的。
通过 var
关键字声明的变量默认值为 undefined
。
现在创建阶段完成,我们可以实际执行代码了。在我们声明任何函数或变量之前,一起看看在文件头部若有 3 个 console.log 语句会发生什么。
由于函数声明是对整个函数代码的引用,所以我们可以在创建它们之前调用🔥。
当我们在引用一个通过 var
声明的变量之前使用它时,只会返回它存储的默认值:undefined
!可是,这有时会导致不可预期的
的行为。在多数情况下,代表你是无意引用它(你可能并不希望它是 undefined
)。
为了阻止意外引用一个 undefined
变量,就像使用通过 var
关键字定义的变量,无论何时我们使用一个未初始化的变量时 ReferenceError
错误将会被抛出。在实际声明变量之前的区域,称为:temporal dead zone 你不可以在变量(也包括 ES6 中的 class)初始化之前使用它。
当浏览器引擎执行过我们实际声明变量的代码时,内存中变量的值将会被我们声明它时赋值的值覆盖。
都结束了!快速总结下:
- 当我们执行代码时,函数和变量被存储在执行上下的内存中,这称为提升。
- 函数被存储为指向整个函数的代码引用中,通过
var
关键字声明的变量默认值为undefined
,而let
和const
关键字声明的变量则是未初始化。
我希望 hosisting 这块知识变得清晰一些了,特别是当我们执行代码,查找到底发生了什么时。像往常一样,不要担心如果它还没有带来很实际的意义。你若经常使用它,就会越来越适应它。