javascript中的变量提升

介绍: (Introduction:)

This article is in continuation of my previous article: Javascript Variable Scopes

本文是我上一篇文章的延续: Javascript变量范围

Hoisting is a tricky and very important topic in javascript. Lot of questions asked in javascript interviews are based on hoisting.

提升是JavaScript中一个棘手且非常重要的主题。 JavaScript面试中提出的许多问题都基于提升。

In this article, we will go through variable hoisting in javascript and see how it affects the desired output.

在本文中,我们将使用javascript进行变量提升,并了解它如何影响所需的输出。

So, let’s not wait further and dive into concept of hoisting.

因此,让我们不要再等下去了,而是要探讨起重的概念。

什么是可变吊装? (What is Variable Hoisting?)

Hoisting is a JavaScript mechanism where variables declarations are moved to the top of their scope before code execution.

提升是一种JavaScript机制,其中变量声明在代码执行之前移至其作用域的顶部。

This means when javascript engine compiles your code, all variable declarations using var are lifted to the top of their functional/local scope (if declared inside a function) or to the top of their global scope (if declared outside of a function) regardless of where the actual declaration has been made.

这意味着当javascript引擎编译您的代码时,所有使用var变量声明都会提升到其功能/本地范围的顶部(如果在函数内部声明)或全局范围的顶部(如果在函数外部声明),无论实际声明所在的位置。

Basically, it gives us an advantage that no matter where variables are declared, they are moved to the top of their scope regardless of whether their scope is global or local. It allows us to use variables before it is declared in our code.

基本上,它为我们提供了一个优势,即无论在何处声明变量,无论变量的作用域是全局的还是局部的,它们都将移至其作用域的顶部。 它允许我们在代码中声明变量之前使用变量。

The following example declares variable studentName and assign value John to it:

以下示例声明变量studentName并为其分配值John

console.log(studentName);  // usage
var studentName = 'John'; //declaration & assignment

以上代码的输出是什么? (What will be the output of above code?)

  1. Uncaught ReferenceError: name is not defined

    Uncaught ReferenceError: name is not defined

  2. John

    John

  3. undefined

    undefined

It turns out that third option is correct answer.

事实证明,第三个选项是正确的答案。

说明: (Explanation:)

In the above code, we tried to console the variable studentName which was declared and assigned later then using it, the compiler gives us undefined which we didn't expected as we should have got ReferenceError as we were trying to use studentName variable even before declaring it. But the interpreter sees this differently, the above code is seen like this:

在上面的代码中,我们尝试控制台变量studentName ,该变量随后被声明并分配,然后使用它,编译器为我们提供了undefined的变量,这是我们所不期望的,因为我们在尝试使用studentName变量之前就应该获得ReferenceError,甚至在声明之前它。 但是解释器对此有不同的看法,上面的代码如下所示:

//how interpreter sees the above code
var studentName;
console.log(studentName);
studentName = 'John';

这里要注意的事情: (Things to note here:)

  • Variable declaration studentName is moved to top.

    变量声明studentName移到顶部。

  • Only thing that gets moved to the top is the “variable declarations”, not the actual value given to the variable. Therefore, output is undefined instead of John.

    唯一移到顶部的是“变量声明”,而不是赋予变量的实际值。 因此,输出是undefined而不是John

ES6: letconst关键字。 这些也悬挂了吗? (ES6: let & const keywords. Are these also hoisted?)

Variables declared with let and const are also hoisted. Where they differ from other declarations in the hoisting process, is in their initialisation.

letconst声明的变量也将被提升。 在起吊过程中它们与其他声明不同的地方在于它们的初始化。

Let’s look at an example:

让我们看一个例子:

console.log(studentName);  
//ReferenceError: studentName is not defined
let studentName = 'John';

为什么会出现此错误? (Why this error?)

Variables declared with let, const, and class are hoisted but remain uninitialised. These variable declarations only become initialised when they are evaluated during runtime. The time between these variables being declared and being evaluated is referred to as the temporal dead zone. If you try to access these variables within this dead zone, you will get the reference error above.

用let,const和class声明的变量被挂起,但未初始化。 这些变量声明仅在运行时对其求值时才被初始化。 在声明和评估这些变量之间的时间称为时间死区 。 如果您尝试在此盲区中访问这些变量,则会在上面得到参考错误。

  • JavaScript runs its compilation phase and sees let studentName, hoists that variable, but does not initialise it.

    JavaScript运行其编译阶段,并看到let studentName提升了该变量,但没有对其进行初始化。

  • Next, in the execution phase, console.log() is invoked and passed the argument studentName.

    接下来,在执行阶段,将调用console.log()并将其传递给参数studentName

  • Because the variable has not been initialised, it has not been assigned a value, and thus the reference error is returned stating that studentName is not defined.

    由于尚未初始化变量,因此尚未为其分配值,因此返回了引用错误,指出未定义studentName

console.log(studentName); 
// ReferenceError: studentName is not defined
const studentName = 'John';

Much like the let keyword, using const before declaration throws a Reference error.

就像let关键字一样,在声明之前使用const会引发Reference错误。

Hence, to err on the side of caution, we should declare then assign our variables to a value before using them.

因此,为了谨慎起见,我们应该声明然后在使用变量之前将变量赋值。

摘要: (Summary:)

  • JavaScript hoisting occurs during the creation phase of the execution context that moves the variable declarations to the top of the script.

    JavaScript提升发生在执行上下文的创建阶段,该阶段将变量声明移到脚本的顶部。
  • While using var, trying to use undeclared variables will lead to the variable being assigned a value of undefined upon hoisting.

    在使用var ,尝试使用未声明的变量将导致在提升时为该变量分配一个undefined的值。

  • While using es6 let and const, using undeclared variables will lead to a Reference Error because the variable remains uninitialised at execution.

    在使用es6 letconst ,使用未声明的变量将导致Reference Error因为该变量在执行时仍未初始化。

  • We should make it a habit to declare and initialise JavaScript variables before use.

    我们应该养成使用前声明和初始化JavaScript变量的习惯。

That’s it for now. Thank you for taking time to read this article. Do provide feedback and comments. I’ll cover more topics like difference between var, let and const in upcoming posts. Keep following!

现在就这样。 感谢您抽出宝贵的时间阅读本文。 提供反馈和评论。 我将在以后的文章中讨论更多主题,例如var,let和const之间的区别。 继续关注!

翻译自: https://medium.com/@vivek.ece07/variable-hoisting-in-javascript-ee5161aec05d

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值