javascript中终止_javascript中的吊装概念

javascript中终止

Hoisting in English language means to pull something up. You must have been to the National Day celebration event, aren’t you? On that occasion, the chief guest approaches the mast and he pulls some rope and the flag goes up, right. This is exactly what happens in JavaScript albeit with some change. In JavaScript the functions and variables are hoisted to the top of the scope. Let’s see some use cases for that to understand the hoisting concept better. But before that let’s gather some common knowledge about the process.

用英语吊起意味着拉起一些东西。 您一定去过国庆庆典活动,不是吗? 在这种情况下,主要客人走近桅杆,他拉了一些绳子,旗子升起,正确。 尽管有一些更改,但这正是JavaScript中发生的情况。 在JavaScript中,函数和变量被提升到作用域的顶部。 让我们看一些用例,以更好地理解吊装概念。 但是在此之前,让我们收集有关该过程的一些常识。

First thing first. Just keep it in mind that whenever the browser engine is reading your code and giving you the output, mostly it is a two-phase process.

首先是第一件事。 请记住,每当浏览器引擎读取代码并提供输出时,大多数情况下这是一个两阶段的过程。

  1. Hoisting phase

    吊装阶段
  2. Execution phase

    执行阶段

In the hoisting phase, the browser takes all your available functions and variables, takes them up to the highest position in the available scope depending upon whether they are declared locally or globally and create space for them in the memory. Wait a moment. Declaration!!! Is it not the same as an assignment?

在提升阶段,浏览器将获取所有可用的函数和变量,并将它们带到可用范围内的最高位置,具体取决于它们是在本地还是全局声明,并在内存中为其创建空间。 等一会。 宣言!!! 它与作业不同吗?

No, these two stages are different. JavaScript gives us the flexibility to declare and assign variables with a single statement, but the interpreter treats the statement differently.

不,这两个阶段是不同的。 JavaScript使我们可以灵活地使用单个语句声明和分配变量,但是解释器对语句的处理方式有所不同。

Suppose you write like this.

假设您这样写。

var myVar = 10;

The interpreter will treat the above code in two statements like this.

解释器将在两个这样的语句中处理以上代码。

var myVar; // declaration stage 
myVar = 10; // assignment stage

Now that we know the overall concept of hoisting let’s apply it in the JavaScript context and see what are the various scenarios where we need to be cautious while writing code.

现在我们知道了提升的总体概念,让我们将其应用到JavaScript上下文中,看看在编写代码时需要谨慎的各种情况。

The difference between “undefined” and “Is not defined”

“未定义”和“未定义”之间的区别

These two phrases seem similar, but in JavaScript context they are completely different. While undefined is a value, ‘is not defined’ is a type of reference error. Let’s see how.

这两个短语看起来很相似,但是在JavaScript上下文中它们是完全不同的。 尽管undefined是一个值,但“ undefined”是一种参考错误。 让我们看看如何。

console.log(var1); 
var var1 = 10;

The above code prints undefined in the console because the variable is assigned later than the console.log statement. Essentially the interpreter follows the following steps to execute the above code.Like we have already discussed, the declaration phase comes before the assignment phase. So, the above code looks like the below to the interpreter.

上面的代码在控制台中未打印,因为该变量的分配晚于console.log语句。 实质上,解释器遵循以下步骤来执行上述代码。正如我们已经讨论过的那样,声明阶段位于赋值阶段之前。 因此,上面的代码对于解释器来说类似于下面的代码。

var var1; 
console.log(var1);
var1 = 10;

Here what is happening is, on step1, the interpreter allocates a memory space for the variable var1. Now that the variable is not yet assigned any value, it assigns a value undefined to the memory location. So now the memory location described by var1 contains undefined. On the next line when we try to access the memory location by referring to var1, it fetches the value from the memory location and till now it contains undefined. So, the console statement prints undefined.

在这里发生的是,在步骤1,解释器为变量var1分配了一个存储空间。 现在,该变量尚未分配任何值,它将为存储位置分配一个未定义的值。 因此,现在var1描述的内存位置包含未定义。 在下一行中,当我们尝试通过引用var1来访问存储位置时,它会从存储位置获取值,直到现在它仍包含未定义的值。 因此,控制台语句打印未定义。

On the next step, the variable is assigned a value 10 and now the memory location described by var1 contains the value 10. That is the reason why, when we try to access a variable before it is assigned, gives us an undefined.

下一步,为变量分配一个值10,现在var1描述的内存位置包含值10。这就是为什么当我们尝试在分配变量之前访问变量时却给我们一个未定义的原因。

Next, we do something like this.

接下来,我们做这样的事情。

console.log(var2);

Here in this case the browser throws an error saying Uncaught Reference Error: var2 is not defined. Here the error clearly says that it is a reference error because since the variable is not declared, there is no memory location allocated to the var2 variable and it is not able to reference it. That is why the error comes up.

在这种情况下,浏览器将抛出一个错误,提示未捕获的参考错误:未定义var2。 这里的错误清楚地表明这是一个引用错误,因为由于未声明该变量,因此没有分配给var2变量的内存位置,并且它无法引用该变量。 这就是为什么出现错误。

The “type of” ambiguity

“类型”的歧义

The type of operator returns the type of a variable such that type of (1) returns “number” and type of (null) returns “object”. Now in the context of this article, if we write the below code onto the console, the type of operator returns “undefined”.

运算符的类型返回变量的类型,以使(1)的类型返回“数字”,而(null)的类型返回“对象”。 现在,在本文的上下文中,如果我们将以下代码写入控制台,则运算符的类型将返回“ undefined”。

console.log(typeof var1); //undefined (when variable is not declared or assigned)console.log(typeof var2); // undefined (when variable is assigned later)var var2 = 10; 
var newVar = 10; console.log(typeof newVar); // number (when variable is assigned before typeof assertion)

This leads us to the conclusion that in JavaScript, a variable is assigned a value of undefined if it is not assigned to any other value except undefined before referring to it.

这导致我们得出以下结论:在JavaScript中,如果在引用变量之前未将变量赋给除undefined以外的任何其他值,则该变量会被赋值为undefined。

If it is not var, then it is GLOBAL

如果不是var,则为GLOBAL

This is a very typical use case of hoisting. Let’s see that by an example.

这是提升的一个非常典型的用例。 让我们来看一个例子。

foo();function foo() { var1 = 10; var var2 = 20;}console.log(var1); // 10console.log(var2); // Uncaught ReferenceError: var2 is not defined

What happened here. For the first variable declared inside the function, we have omitted the var keyword. So as soon as the function is called, the variable is assigned to the global namespace and hoisted there. That is why when we try to access the variable outside of the function it is becoming accessible.

这里发生了什么。 对于在函数内部声明的第一个变量,我们省略了var关键字。 因此,一旦调用该函数,该变量便被分配给全局名称空间,并在那里被提升。 这就是为什么当我们尝试在函数外部访问变量时,它变得可访问的原因。

Had we put the var keyword before that variable, it would have been a local variable to the function body and would be inaccessible outside of the function, which is the case for the var2 variable.

如果我们将var关键字放在该变量之前,则该变量将是函数主体的局部变量,并且在函数外部将无法访问,而var2变量就是这种情况。

Wait a second. If you have not observed yet, here in this example we are calling the function even before its declaration. Let’s save this concept for one of the upcoming pointers about function hoisting.

等一会儿。 如果您还没有观察到,在此示例中,我们甚至在声明函数之前就调用该函数。 让我们将此概念保存为有关函数提升的即将到来的指针之一。

let & const: the ES6 big boyz

let&const:ES6大男孩

Till ES6 was released there were only two types of scopes available in JavaScript, one being the global scope and the other one the local scope. But, with the release of ECMAScript2015, the dynamics got changed about the declarations of variables. It introduced two new keywords namely let and const. While the former is used to define a block scoped variable the latter came to be used for defining immutable values. Here we will see how the hoisting of the values change with the use of let and const keywords. Now let’s see some of the possible use cases and their corresponding outputs with let and const.

直到ES6发行,JavaScript中只有两种类型的作用域,一种是全局作用域,另一种是局部作用域。 但是,随着ECMAScript2015的发布,变量声明的动态性发生了变化。 它引入了两个新的关键字,即let和const。 前者用于定义块范围变量,而后者则用于定义不可变值。 在这里,我们将看到使用let和const关键字改变值的提升方式。 现在,让我们看看一些可能的用例以及它们与let和const对应的输出。

console.log(var1); // Uncaught Reference error var1 is not definedlet var1 = 10;let var2;console.log(var2); // undefinedvar2 = 10;console.log(var1); // Cannot access 'var1' before initializationconst var1 = 10;

★ A constant declaration should always accompany an initialization.

★常量声明应始终伴随初始化。

Function hoisting with declaration

带声明的功能提升

The interpreter always takes the functions to the top of the execution context and that is why we can access the functions even before declaring them like below.

解释器始终将功能放在执行上下文的顶部,这就是为什么我们甚至在像下面这样声明它们之前也可以访问这些功能的原因。

foo();function foo() {alert('I am being called!!!');}

Function hoisting with function expressions

函数表达式的函数提升

When we write a function as an expression, the interpreter treats it as a normal variable and hoists it to the top of the scope. Thereby when we try to call the function through an expression even before it is declared, the value remains undefined for the function and we get an error saying ‘foo is not a function’ as given in the example below.

当我们将函数编写为表达式时,解释器将其视为普通变量并将其提升到作用域的顶部。 因此,当我们甚至在声明表达式之前尝试通过表达式调用函数时,该函数的值仍未定义,并且会收到错误消息,说明“ foo不是函数”,如下面的示例所示。

foo();var foo = function () {alert('');}

Class hoisting with declaration

带声明的类吊装

A ES6 class is not hoisted when it is declared. We can’t access a class before it is declared. An example in this context is given below.

声明时不会悬挂ES6类。 在声明类之前,我们无法访问它。 下面给出了这种情况下的一个例子。

// instantiating a class before it is declaredvar john = new Person('john', 28);class Person {  constructor(name, age) {    this.name = name;    this.age = age; }}

The above code throws an error saying Uncaught Reference Error: Person is not defined which proves that class declarations are not hoisted to the top of the scope and we can’t access a class before it is declared. Let’s see what happens when we write a class expression.

上面的代码抛出一个错误,提示未捕获的引用错误:未定义Person ,这证明类声明未提升到作用域的顶部,并且在声明类之前我们无法访问它。 让我们看看编写类表达式时会发生什么。

Class hoisting with expression

带表达的类吊装

When a class is written in the form of an expression, the interpreter treats it as a normally hoisted variable. Let’s see this thing in the form of two examples.

当类以表达式形式编写时,解释器将其视为正常提升的变量。 让我们以两个示例的形式看待这个问题。

console.log(Person1); // undefinedvar Person1 = class {  constructor(name, age) {    this.name = name;    this.age = age;}}

The above code gives undefined as the variable is hoisted to the top of the scope before it is initialized with a class expression.

上面的代码给出undefined,因为在使用类表达式初始化变量之前将其提升到范围的顶部。

var john = new Person('john', 28);console.log(john);//Person {name: "john", age: 28}var Person = class {  constructor(name, age) {    this.name = name;    this.age = age;  }}

The above code will throw an error saying Uncaught TypeError: Person is not a constructor which is for obvious reasons.

上面的代码将引发错误,提示Uncaught TypeError:Person不是构造函数 ,这是有明显原因的。

Order of precedence for functions and variables in hoisting

提升中功能和变量的优先顺序

This order of precedence defines which value the execution context takes up in case of functions and variables declaration and assignment. It is governed by two simple rules.

此优先顺序定义在函数和变量声明和赋值的情况下,执行上下文采用哪个值。 它受两个简单规则支配。

❖ Variable assignment is prioritized than function declaration

❖变量赋值优先于函数声明

❖ Function declaration is prioritized than variable declaration

❖函数声明比变量声明优先

We can understand the above two rules through two simple examples as given below.

我们可以通过下面给出的两个简单示例来理解上述两个规则。

Variable assignment is prioritized than function declaration

变量赋值优先于函数声明

In this example we create a function and a variable with the same name and assign some value to the variable. Then we try to access the variable first as a reference and then as a function. We can see that the variable assignment has taken precedence over the function declaration

在此示例中,我们创建了一个具有相同名称的函数和变量,并为该变量分配了一些值。 然后,我们尝试先访问变量作为参考,然后访问函数。 我们可以看到变量赋值优先于函数声明

var name = 'john';function name() {alert('my name is john');} console.log(name); // johnname(); // Uncaught TypeError: name is not a function

Function declaration is prioritized than variable declaration

函数声明比变量声明优先

In this example we take a function and a variable with the same name, but we don’t assign any value to the variable. Then we try to access both of these and see what happens.

在此示例中,我们采用了具有相同名称的函数和变量,但是没有为变量分配任何值。 然后,我们尝试访问这两者,然后看看会发生什么。

var name;function name() {alert('my name is john');}console.log(name); // gives the body of the function

This is pretty much it you need to know about hoisting in JavaScript.

您几乎需要了解有关使用JavaScript进行吊装的知识。

翻译自: https://medium.com/swlh/the-hoisting-concept-in-javascript-fbb533dd42ae

javascript中终止

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值