Hoisting is one of those terms that every JS dev has heard of because you googled your annoying error and ended up on StackOverflow, where this person told you that this error was caused because of hoisting 🙃 So, what is hoisting? (FYI - scope will be covered in another post, I like to keep posts small and focused)
变量提升是每个 JS 开发人员都听说过的那些术语之一,因为您在 Google 上搜索了烦人的错误并最终进入 StackOverflow,此人告诉您此错误是由于 Hoisting(变量提升) 引起的 🙃 那么,变量提升是什么?(仅供参考- Scope(作用域) 将在另一篇文章中介绍,我希望保持文章小而专注)
If you’re new to JavaScript, you may have experienced “weird” behavior where some variables are randomly undefined
, ReferenceError
s get thrown, and so on. Hoisting is often explained as putting variables and functions to the top of the file but nah, that’s not what’s happening, although the behavior might seem like it 😃
如果您不熟悉 JavaScript,则可能会遇到”怪异”的行为,其中某些变量是随机变量
undefined
,ReferenceError
会被抛出等等.变量提升通常被解释为将 变量和函数放在文件的顶部,但是不,这不是发生的事情,尽管行为看起来像这样.
When the JS engine gets our script, the first thing it does is setting up memory for the data in our code. No code is executed at this point, it’s simply just preparing everything for execution. The way that function declarations and variables are stored is different. Functions are stored with a reference to the entire function.
当 JS 引擎获取我们的脚本时,它要做的第一件事就是为代码中的数据 设置内存.在这一点上,没有代码被执行,只是在准备要执行的所有内容.函数声明和变量的存储方式不同.函数以 对整个函数的引用存储.
With variables, it’s a bit different. ES6 introduced two new keywords to declare variables: let
and const
. Variables declared with the let
or const
keyword are stored uninitialized.
对于变量,则有所不同.ES6 引入了两个新的关键字来声明变量:
let
和const
.用let
或const
关键字声明的变量 未初始化 .
Variables declared with the var
keyword are stored with the default value of undefined
.
使用
var
关键字声明的变量的默认值存储为undefined
.
Now that the creation phase is done, we can actually execute the code. Let’s see what happens if we had 3 console.log statements on top of the file, before we declared the function or any of the variables.
现在创建阶段已经完成,我们可以实际执行代码了.让我们看看如果在声明函数或任何变量 之前 在文件顶部有 3 个 console.log 语句,会发生什么情况.
Since functions are stored with a reference to the entire function code, we can invoke them even before the line on which we created them! 🔥
由于函数是在引用整个函数代码的情况下存储的,因此我们甚至可以在创建它们的行 之前 调用它们!🔥
When we reference a variable declared with the var
keyword before their declaration, it’ll simply return its default value that it was stored with: undefined
! However, this could sometimes lead to “unexpected” behavior. In most cases this means you’re referencing it unintentionally (you probably don’t want it to actually have the value of undefined
) 😬
当我们在变量声明
var
之前引用用关键字声明的变量时,它将简单地返回其存储在其中的默认值:undefined
!但是,这有时可能导致”意外”行为.在大多数情况下,这意味着您无意中引用了它(您可能不希望它实际上具有的值undefined
)😬
In order to prevent being able to accidentally reference an undefined
variable, like we could with the var
keyword, a ReferenceError
gets thrown whenever we try to access uninitialized variables. The “zone” before their actual declaration, is called the temporal dead zone: you cannot reference the variables (this includes ES6 classes as well!) before their initialization.
为了防止
undefined
像使用var
关键字那样意外地引用变量,每当我们尝试访问 未初始化 的变量时,都将引发ReferenceError
.在它们实际声明之前的”区域”称为 暂存死区:在初始化之前,您不能引用变量(也包括 ES6 类!).
When the engine passes the line on which we actually declared the variables, the values in memory are overwritten with the values we actually declared them with.
当引擎通过我们实际声明变量的行时,内存中的值将被我们实际声明它们的值覆盖.
(Oops I notice now this should be number 7. Will update asap 😬)
(糟糕,我现在注意到这应该是数字 7.将尽快更新).
All done! 🎉 Quick recap:
全做完了!🎉 快速回顾:
- Functions and variables are stored in memory for an execution context before we execute our code. This is called hoisting.
- Functions are stored with a reference to the entire functions, variables with the
var
keyword with the value ofundefined
, and variables with thelet
andconst
keyword are stored uninitialized.
- 在执行代码之前,将函数和变量存储在内存中以用于执行上下文.这称为 变量提升.
- 函数以对整个函数的引用存储,带有
var
关键字的变量值为undefined
,而带有let
和const
关键字的变量 未初始化 .
I hope that the term hoisting is a bit less vague now that we’ve looked at what’s happening when we execute our code. As always, don’t worry if it still doesn’t make a lot of sense yet. You’ll get a lot more comfortable with it the more you work with it. Feel free to ask me for help, I’d love to help you! 😃
我希望 提升 术语一词的含义不再那么模糊,因为我们已经研究了执行代码时发生的情况.与往常一样,不要担心它是否仍然没有任何意义.您使用它的次数越多,您将对其感到更加自在.随时向我寻求帮助,我很乐意为您服务!😃