Javascript中的Hoisting完整概述

273 阅读5分钟

目录

阅读时间: 5 分钟

在javascript中,Hoisting指的是解释器在执行代码之前将函数、变量(var、let、const)或类的声明移到其范围的顶部的过程,或者我们可以说在编译代码的时候。

另外,Hoisting是JavaScript中的一个概念,而不是一个特性。所以我们来看看这个概念。

JavaScript吊起的介绍

在这篇博客中,我们将研究在JavaScript中如何发生提升机制。但在我们深入研究之前,让我们先来了解一下什么是提升。

当js编译器编译代码并检查声明时,Hoisting就开始工作了。

js编译器会将所有的声明移到范围的顶部[变量的声明以及函数的声明。

当编译器将所有的声明移到作用域的顶部时,就不会有错误。然而,事实是,提升机制只移动声明,不移动赋值。

在使用javascript的过程中,你还发现,当声明和初始化出现在同一行代码中时,提升是不可能的。

所以,我们可以说提升只适用于声明,而不是初始化。

JavaScript Hoisting

悬挂也允许开发者在代码中声明之前使用函数。

悬挂变量

下面提到了JavaScript的生命周期,并且说明了变量的声明和初始化的顺序。

With Hoisting

例子。 悬挂

例子。 悬挂不适用于初始化的变量

当js编译器编译代码时,所有变量和函数的声明都在范围的顶部。

然而,重要的是要记住,在后台,JavaScript正在虔诚地声明然后初始化我们的变量。

Flow of declaration

变量托管

JavaScript的提升是可以用来处理变量(var)的。你可以很容易地在代码中使用一个变量,在它的声明和初始化之前。

我们已经定义了javascript只对声明进行提升,而不是对初始化进行提升。

变量提升

在这里,我们先声明,然后在使用var后初始化它的值。默认情况下,var的初始化是未定义的。

当解释器挂起一个用(var)声明的变量时,它将初始化其值为undefined 。下面的第一行代码将输出undefined

我们可以通过将声明和赋值分成两步来手动实现这种相同的行为。

var hoisting

如果我们在同一行中声明和初始化变量,也会发生同样的事情。

var image

正如我们已经提到的,提升对声明起作用。如果我们只初始化值,就不会起作用。

所以,在变量被初始化之前试图读取它的结果是 [ReferenceError](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/ReferenceError)异常。

在赋值前使用一个未声明的变量也会抛出一个ReferenceError ,因为没有声明被吊起。

但是请注意,初始化也会导致声明(如果尚未声明)。

下面的代码片断显示了上述语句的例子。

var hoisting

值得庆幸的是,ECMAScript 2015中引入的letconst 变量的行为是不同的。

let和const吊起

letconst 声明的变量被挂起,但没有用默认值初始化。在一个letconst 变量被声明之前访问它,会导致一个 [ReferenceError](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/ReferenceError):

let and const hoisting

永远记住一个重要的观点,代码的执行顺序并不重要,重要的是代码写入文件的顺序。

类挂起

这里我们使用类声明,然后初始化类。默认的行为是,javascript有一个对类的引用。

然而这个类在默认情况下并没有被初始化,所以在执行初始化的那一行之前,任何使用它的代码都会抛出一个 [ReferenceError](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/ReferenceError).

功能寄存

在功能寄存中,javascript允许我们在函数声明前或定义函数前调用该函数。

JavaScript编译器将函数定义放在顶部,与变量声明的方式相同。

悬挂的好处之一是,它可以让你在代码中声明函数之前就使用它。

function hoisting

如果没有提升,你将不得不写同样的代码,就像这样。

function hoisting 函数声明有资格被提升,但函数表达式没有资格被提升,这应该是有意义的。因为我们已经了解到,变量赋值是不被提升的。

如果我们试图调用函数表达式所赋值的变量,我们会得到一个TypeErrorReferenceError,这取决于变量的范围。

总结

悬挂变量

它是在块的顶部用let或const关键字定义一个变量。

但是如果你在一个较老的代码库中工作,或者因为其他原因不得不使用var,所有的文档都建议你把var声明写在尽可能靠近其作用域顶部的地方。

这将使你的变量的范围更加清晰。你也可以使用ESLint规则,这将确保你不会在变量声明之前使用它。

函数悬挂

函数悬挂很有用,因为我们可以将函数的实现隐藏在文件的较远处,让读者关注代码在做什么。

我们也可以定义它,因为我们可以直接打开文件,检查出代码在做什么,而不需要看一下实现的步骤。
然而,在声明之前使用函数,是开发者的偏好或项目情景的问题。

JavaScript提升发生在执行上下文的创建阶段,它将变量和函数声明移到脚本的顶部。
JavaScript引擎提升了用let关键字声明的变量,但它并没有像用var关键字声明的变量那样初始化这些变量。
JavaScript引擎并不提升函数表达式和箭头函数

总结

在声明JavaScript的函数和变量时,记住几件事是很重要的: 变量赋值优先于函数声明。
函数的声明优先于变量的声明。

谢谢你的阅读,我希望这篇博客能帮助你了解JavaScript中的吊装。