javascript:_使用JavaScript吊装:分步说明

javascript:

To understand what hoisting in JavaScript is, let us first refer to a definition of this word:“Hoist — raise (something) using ropes and pulleys” (Merriam-Webster Dictionary)This term is often used in terms of raising a flag, for example:Pirates hoisted a black flag approaching their enemy's land as a signal they are going to attack.

为了理解JavaScript中的提升,让我们首先参考该词的定义:“提升-使用绳索和滑轮提升(某些东西)”(Merriam-Webster词典)该术语通常用于升起旗帜,例子: 海盗举起一面黑旗,逼近敌人的土地,以示他们要进攻的信号。

Therefore, hoisting as a noun can be defined as an act of raising something. While hoisting in JavaScript gives its hoisting much more amicable meaning than pirates, its intention is still the same — to declare an act before its execution.

因此,吊装为名词可以定义为举起某物的行为。 尽管使用JavaScript进行吊装比起海盗盗版具有更友好的含义,但其意图仍然是相同的-在执行之前声明一个行为。

Variable HoistingVarIn programming, we use variables. Variable is a value that can change, depending on conditions or on information passed to the program. Let take an example using the analogy with pirates. Imagine, we decided to build a Pirates Attack game app. There are two players-one plays for pirates, and another one — for defendants. We approached the part in our code, where we need to make sure pirates have their flags on the ship when they are leaving their land to enemies’ land to raise it. We do not know yet what color of the flag pirates will raise (it depends on the second player’s actions). While approaching the enemy’s land, the captain may look at the binocular and sees that the land is full of gold, then he will give an order to raise a black flag. Otherwise, he might look at the land and see that his old buddy from elementary school is living there, and he does not want to attack him, then he will give an order to raise a white flag. All we care for now is that pirates ship need a flag variable in our app sometimes in the future, and we can determine the value later.

变量提升 Var在编程中,我们使用变量。 变量是一个可以更改的值,具体取决于条件或传递给程序的信息。 让我们举一个与海盗类比的例子。 想象一下,我们决定构建一个Pirates Attack游戏应用程序。 有两个玩家,一个是海盗游戏,另一个是被告。 我们在代码中使用了该部分,我们需要确保海盗在将土地留给敌人的土地升起时在船上悬挂旗帜。 我们尚不知道海盗会升起什么颜色(取决于第二名玩家的行动)。 当接近敌人的土地时,机长可能会注视着双筒望远镜,发现土地上满是黄金,然后他会下令举起黑旗。 否则,他可能会看着这片土地,看到他小学的老伙伴住在那里,并且他不想攻击他,那么他将下令举起白旗。 我们现在关心的是,将来有时海盗船在我们的应用程序中需要一个flag变量,我们可以稍后确定该值。

Image for post

In JavaScript language, this act is called *variable declaration*. We declared a variable, but we have not assigned it yet.

在JavaScript语言中,此行为称为*变量声明*。 我们声明了一个变量,但尚未赋值。

Let come back to our pirates. The captain has looked into the binocular and saw lots of gold on enemies’ land. He decides to invade the enemy. He gives to raise a black flag on the ship; in other words, he assigns to raise a black flag. As a programmer, you need to assign a var flag to be a black one.

让我们回到海盗。 船长看着双筒望远镜,在敌人的土地上看到了很多金子。 他决定入侵敌人。 他给在船上升起黑旗。 换句话说,他指定举起黑旗。 作为程序员,您需要将var标志分配为黑色标志。

Image for post

The next thing to do is to raise this black flag on the ship. Now you need to have a method called raiseFlag() where you will pass `flag` as an argument.

接下来要做的是在船上升起黑旗。 现在,您需要有一个名为raiseFlag()的方法,您将在其中传递“ flag”作为参数。

Image for post

Let us see the steps we took to use our variable:

让我们看看使用变量的步骤:

1. We declared the variable `flag`2. We assigned the value `black flag` to our variable 3. We executed the variable in our `raiseFlag()` function.

1.我们声明了变量`flag`2。 我们为变量3分配了“ black flag”值。我们在“ raiseFlag()”函数中执行了该变量。

What would happen if we change the order of our commands? The captain told to bring a flag on the ship without specifying which one, and then, after looking in the binocular, he gives a command to raise a flag. What flag will the crew raise? Let us see.

如果我们更改命令顺序会怎样? 船长告诉他在船上带上一面旗帜,但未指明是哪一个,然后,他在望着双筒望远镜后发出了升旗的命令。 机组人员将升起什么旗帜? 让我们看看。

Image for post

Oops! `Flag` is `undefined`.

糟糕! 标记是未定义的。

Now let us imagine that the captain is getting old and forgets to tell what flag to raise and tell the crew to bring the flag on the ship at all!

现在,让我们想象一下船长正在变老,却忘了告诉他升起什么旗帜,而告诉船员根本没有把旗帜升上船!

Image for post

`Flag` is `undefined` again. However, we have not run into the error, trying to execute the undeclared variable. The code was still running; it just gives us an undesired result — the variable is undefined. It is what hoisting does! JavaScript has hoisted (invisibly to us, behind the scene) the variable declaration above the rest of the code. Due to hoisting, JavaScripts can identify the variable declaration first and runs the rest of the code. From JavaScript’s point of view, there is no difference between the last two snippets of code — it sees it as shown on the first snippet. Due to this reason, we have to be careful and always declare and assign the variable simultaneously:

标记再次是未定义的。 但是,我们没有遇到错误,试图执行未声明的变量。 代码仍在运行; 它只会给我们带来不良结果-变量未定义。 这就是起吊! JavaScript已将变量声明悬挂在后台(对我们来说不可见)在代码其余部分的上方。 由于提升,JavaScript可以首先识别变量声明,然后运行其余代码。 从JavaScript的角度来看,最后两个代码段之间没有区别-它如第一个代码段所示。 由于这个原因,我们必须小心并始终同时声明和分配变量:

Image for post

LetThe variables declared with `var` keyword are function scoped (we can see it throughout the entire function). Now let us examine what happens when we use block-scoped variables defined with `let` and `const` keywords.

让我们用`var`关键字是函数作用域声明的变量(我们可以看到它在整个功能)。 现在让我们检查一下当我们使用由`let`和`const`关键字定义的块范围变量时会发生什么。

Image for post

If we try to call a `let `variable before we declared and initialized it, we do not get undefined anymore, but we see a `Reference Error: variable is not defined`. It means that we can no longer to execute our code before the variable is declared, and JavaScript can no longer initialize the variable behind the scene to run the following code.Now, let us try to declare a variable before the execution code, and assign it after.

如果我们在声明和初始化变量之前尝试调用`let`变量,则不会再出现未定义的情况,但是会看到“参考错误:未定义变量”。 这意味着我们无法在声明变量之前执行代码,JavaScript也无法在后台初始化变量以运行以下代码。现在,让我们尝试在执行代码之前声明变量并分配之后。

Image for post

Woohoo! JavaScript will still run the code even if the variable was not assigned yet, and gives us `undefined`. However, such implementation will most likely cause an undesired outcome when you run the application. Again, we come to the importance of declaring and assigning variables before executing them.

hoo! 即使尚未分配变量,JavaScript仍将运行代码,并为我们提供“未定义”。 但是,这样的实现很可能在您运行应用程序时导致不希望的结果。 同样,我们谈到在执行变量之前声明和分配变量的重要性。

ConstThere is one more keyword that ES6 has event a stricter mode for — `const` . It is similar to `let` variable being a block-scoped, but it has its differences. Unlike `let` , `const` is an immutable variable, which means we cannot reassign it to a different value. If `let` allows to execute code when we at least declare the variable before the execution, `const` will not execute code unless a variable was both declared and assigned before execution.

常量还有一个关键字表明ES6具有对const更严格的模式。 它类似于`let`变量是一个块作用域,但有其区别。 与`let`不同,`const`是一个不可变的变量,这意味着我们不能将其重新分配为其他值。 如果`let`允许我们至少在执行之前声明变量时执行代码,则`const`将不会执行代码,除非在执行之前声明和分配了变量。

Image for post

Even if we have declared before execution, but no assigned, the result will be still the same (error):

即使我们已在执行前声明但未分配,结果仍将相同(错误):

Image for post

ES6 still performs hoisting in all cases considered above: `var`, `let`, and `const`. It means that it is still scanning behind the scene to find the declared variable and raise it to the top or above the execution code. However, the difference is in initialization (or assignment) outcomes: •`Var` is initialized with a value “undefined”;•`Let` and const remains initialized (just declared).

在上述所有情况下,ES6仍会执行提升:`var`,`let`和`const`。 这意味着它仍在后台进行扫描以查找已声明的变量,并将其提升到执行代码的顶部或上方。 但是,不同之处在于初始化(或赋值)结果:•“ Var”使用值“ undefined”初始化;•“ Let”和const保持初始化(仅声明)。

Hoisting functionsWe can divide all functions can into two types: Function Declaration and Function Expressions.

提升函数我们可以将所有函数罐分为两种类型:函数声明和函数表达式。

Function DeclarationsFunction declarations, similar to variable declarations, are hoisted. We can call a function before declaring it.

函数声明类似于变量声明的函数声明被提升。 我们可以在声明函数之前调用它。

Image for post

Function ExpressionFunction Expressions are not hoisted. Let us try:

函数表达式表达函数表达式。 让我们尝试:

Image for post

Even if we try to declare a function and express it, JavaScript will only hoist the declaration, but not the assignment. Therefore, it will not see that variable as a function:

即使我们尝试声明一个函数并对其进行表达,JavaScript也只会提升该声明,而不提升该赋值。 因此,它将不会将该变量视为函数:

Image for post

PrecedenceHoisting also has a specific hierarchy:

优先吊装还具有特定的层次结构:

Image for post

When hoisting, JavaScript will always make a priority to hoist variable assignment over function declaration and a function declaration over the variable declaration.

吊装时,JavaScript始终将吊装变量分配的优先级高于函数声明,将函数声明的优先级高于变量声明。

Image for post

As we see, JavaScript applied the assignment to the “flag” given by its variable, not the function declaration. However, if we just declare a variable, then JS will prefer hoisting function declaration instead:

如我们所见,JavaScript将赋值应用于其变量而非函数声明给定的“标志”。 但是,如果我们只声明一个变量,那么JS将更喜欢提升函数声明:

Image for post

ClassesClasses, similar to functions, can be classified as declaration classes and expression classes. Declaration class is hoisted, but remains uninitialized:

与函数相似,类可以分为声明类和表达式类。 声明类已吊起,但未初始化:

Image for post

We get a Reference Error that the flag is not defined, which means that though variable declaration BlackFlag was hoisted, it stayed uninitialized because JS didn’t find what flag is. Yet, once we reverse the order and declare the class variable Flag first, JS can successfully identify the class Flag and use it.

我们收到一个未定义标志的参考错误,这意味着尽管悬挂了变量声明BlackFlag,但由于JS找不到什么标志,因此它未初始化。 但是,一旦我们颠倒了顺序并首先声明了类变量Flag,JS就可以成功识别并使用类Flag。

Image for post

Class expressions, same as function expressions, are not hoisted:

与函数表达式相同的类表达式未悬挂:

Image for post

JS did hoist var Flag, but as a variable declaration (remember the hoisting priority of arable declaration over function declaration?), not as a function. Therefore, it did not hoist the variables assigned to a class.

JS做了葫芦var Flag,但是作为变量声明(还记得耕作声明的起重优先于函数声明吗?),而不是作为函数。 因此,它没有提升分配给一个类的变量。

ConclusionTo summarize all the above, let us bring all the information into a diagram:

结束语总结以上所有内容,让我们将所有信息整合到图表中:

Image for post

翻译自: https://medium.com/swlh/hoisting-in-javascript-a-step-by-step-explanation-9645ce83fbf

javascript:

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值