不畏惧失败是创造力的一个基本要素。——<艾尔文·兰德博士>
介绍
提升是一种JavaScript行为,通常是在给变量赋值或定义函数之前,让变量和函数可用。实际上,它在执行之前将变量、函数和类声明置于其作用域(全局作用域或函数)的顶部。
实际上,JavaScript不会移动或添加代码来提升声明。这些声明在解释器的编译阶段被放入内存中——使它们在代码执行之前可用。
在本文中,我们将学习提升以及它如何影响变量、函数和类。
变量提升
提升的一个关键方面是将声明放入内存——而不是值。
让我们来看一个例子:
1 | console.log(name); // Prints undefined, as only declaration was hoisted |
这是因为JavaScript看到我们在作用域中有一个变量名,并将其放入内存。用var声明的变量在被赋值之前都是未定义的。
使用 let 和 const 进行变量提升
JavaScript 开发人员很少使用 ECMAScript 2015(通常称为 ES6
)中引入 var
let
和 const
关键字。用 let
和const
声明的变量被提升。但是,它们没有使用undefined、 或任何值进行初始化。因此,如果在它们初始化之前使用它们,我们将得到一个ReferenceError.
让我们重新使用相同的示例,但使用 let
代替 var
:
1 | console.log(name); // Uncaught ReferenceError: Cannot access 'name' before initialization |
上面的代码 ReferenceError
在第一行抛出 a并结束执行。
添加 const
关键字是为了在 JavaScript 中引入不可变值 - 初始化后无法更改的值。因此,在使用 const
时,我们必须声明变量并为其赋值。如果我们不这样做,我们会得到一个SyntaxError:
1 | console.log(name); // Uncaught SyntaxError: Missing initializer in const declaration |
就像let,ReferenceError
当我们在初始化之前尝试使用常量时,我们会得到一个:
1 | console.log(name); // Uncaught ReferenceError: Cannot access 'name' before initialization |
函数提升
函数声明在 JavaScript 中被提升。函数声明以关键字function,然后是它的名称和括号中的参数,然后是它的主体。让我们考虑以下代码:
1 | let first_name = "Stack"; |
与变量一样,JavaScript 在执行该范围内的代码之前将函数放入内存中。因此,提升允许我们 concat()
在稍后在代码中定义函数之前调用该函数
虽然提升了函数声明,但函数表达式的工作方式不同。函数表达式是当我们将变量分配给函数时。例如,下面的代码将返回一个错误:
1 | func_express(); // TypeError: func_express is not a function |
使用箭头函数的函数提升
ECMA2015 引入了一种创建匿名函数的新方法,即箭头函数。它们由一对包含 0 个或多个参数的方括号、一个箭头 =>
和大括号中的函数体定义。对于起重,它们的操作与其他功能一样。例如:
1 | arrow_func_express(); // TypeError: arrow_func_express is not a function |
当使用箭头函数或任何其他函数表达式时,我们必须始终在我们的代码中使用它之前定义该函数。这是使用函数表达式的正确方法:
1 | let arrow_func_express = () => { |
类提升
在JavaScript中,类声明会被升起。升起时,类声明未初始化。这意味着,虽然JavaScript可以找到我们创建的类的引用,但在代码中定义该类之前,它不能使用该类。
让我们看看下面的例子,如果试图在类定义之前访问它,就会抛出一个错误:
1 | var person = new Person(); |
ReferenceError
类似于在脚本中初始化之前尝试访问用 let
或const
声明的变量时所发生的情况。
类表达式(将类定义赋给变量)的行为类似于函数表达式。他们的声明被升起,但没有他们的分配价值。
让我们以前面的例子为例,改用类表达式:
1 | var person = new Person(); |
当变量 Person
被提升时,它被赋予值undefined
。由于我们不能将undefined
值用作类,因此 JavaScript 会抛出一个TypeError
.
在使用类声明或类表达式时,我们应该始终在代码中较早地定义类以使用它。正确使用类的方法如下:
1 | class Person { |
结论
JavaScript 提升、变量、函数和类声明。那篇文章展示了提升对我们如何编写 JavaScript 代码的影响。
由于提升,可以在定义之前使用函数声明。然而,为了最大限度地减少获取undefined值以及引用或类型错误的机会,在我们的代码中定义变量、函数表达式和类后使用它们会更安全。
参考
关注【公众号】,了解更多。
赞赏一下 坚持原创技术分享,您的支持将鼓励我继续创作!