JavaScript 中的提升

Q神日志 2023-08-05 10:56:53

目录

  1. 介绍
  2. 提升函数范围变量:var
  3. 提升范围变量:let
  4. 提升常数:const
  5. 起重功能
  6. 吊装课程
  7. 结论

介绍

提升是在代码执行之前移动作用域顶部的所有声明的默认行为。
它给我们带来的优势是:

  • 无论函数和变量在何处声明,它们都会移至其作用域的顶部,无论其作用域是全局的还是局部的。
  • 它允许我们在将函数写入代码之前调用它们。

可变的生命周期: Declaration –> Initialization/Assignment –> Usage

可变的生命周期

JavaScript 允许我们同时声明和初始化变量,这是最常用的模式:

例子2

注意:永远记住,JavaScript 在后台首先声明变量,然后初始化它们。

在 JavaScript 中,未声明的变量在执行分配它们的代码之前并不存在。因此,为未声明的变量赋值会在执行赋值时将其隐式创建为全局变量。这意味着所有未声明的变量都是全局变量。

吊装实例2

函数生命周期: Declaration –> Usage
对于函数,可以声明函数并稍后在应用程序中使用(或调用)。初始化被省略。例如:

函数生命周期

提升函数范围变量:var

与 let/const 相比,使用 var 进行提升有些不同。让我们利用 var 来看看提升是如何工作的:

全球范围

上面的代码解释器有不同的看法:

全局范围 2

使用 var 进行提升在函数作用域变量中的工作方式与上面所示的相同。

提升块范围变量:var

现在告诉我们,我们讨论的是关于一般提升,它 100% 适用于定义的函数和 var 类型变量,因为 let 和 const 类型变量在声明之前无法访问/使用。

但是对于let类型变量来说,提升工作机制是不同的。
就好像我们在声明之前尝试访问 let 变量一样,会导致未定义的 ReferenceError 。

起重块范围变量 1

默认情况下,已声明但未初始化的变量具有未定义的值。

提升块范围变量 ex.2

提升常数:const

常量语句在块作用域内创建并初始化常量:

提升常数 ex.1

定义常量时,必须使用同一个 const 语句中的值对其进行初始化,如果不遵循此规则,SyntaxError: Missing initializer in const declaration则会抛出错误。
声明和初始化后,常量的值不能修改:

提升常数 ex.2

由于临时死区,无法在声明之前访问常量。在声明之前访问时,JavaScript 会抛出错误:ReferenceError:未定义。

提升常数 ex.3

const 提升与使用 let 语句声明的变量具有相同的行为。

提升常数 ex.4

起重功能

在函数声明中提升允许在封闭范围内的任何位置使用该函数,甚至在声明之前。
以下代码从一开始就调用一个函数并定义它:

起重功能 ex.1

该代码运行良好,因为 equal() 是由函数声明创建并提升到作用域顶部的。

注意:函数声明function declaration function <name>() {...}和函数表达式var <name> = function() {...}都用于创建函数,但具有不同的提升机制。

以下示例演示了两种方式之间的区别:

起重功能 ex.2

总和被完全提升,可以在声明之前调用。
然而,减法是使用变量语句声明的,并且也被提升,但在调用时具有未定义的值。此场景根据分配函数的变量类型引发错误

  • 如果变量是 var 那么错误是:`TypeError:减法不是函数。

  • 如果变量是 let 或 const 那么错误是:ReferenceError: Cannot access 'subtract' before initialization

吊装课程

类变量在块作用域的开头注册。但是,如果您尝试在定义之前访问该类,JavaScript 会抛出ReferenceError: Cannot access '<class_name>' before initialization.

所以正确的做法是先声明类,然后用它来实例化对象。

类声明中的提升类似于使用 let 语句声明的变量

让我们看看如果在声明之前实例化一个类会发生什么:

提升等级示例-1

使用变量声明语句创建类也是如此:

提升等级示例-1

结论

帖子的摘要是

  • 提升允许我们使用变量,但这取决于您使用的变量的类型。

  • 提升允许我们在声明之前使用函数,但这取决于您声明函数的方式,无论是简单声明还是使用变量。

  • 提升 var 变量允许我们在声明之前访问/使用该变量,但该值在初始化之前将是未定义的。

  • RefrenceError如果您在声明之前访问/使用 let 变量,则提升 let 变量会导致错误。

  • 已声明但未初始化的 let 变量默认具有未定义值

  • const 提升与使用 let 语句声明的变量具有相同的行为。

  • const 变量必须在声明时初始化。

  • 类必须在访问之前定义,否则程序将出错ReferenceError: Cannot access '<class_name>' before initialization

...全文
580 回复 打赏 收藏 转发到动态 举报
写回复
用AI写文章
回复
切换为时间正序
请发表友善的回复…
发表回复

6

社区成员

发帖
与我相关
我的任务
社区描述
分享
java-rocketmqpygame前端 个人社区 广东省·广州市
社区管理员
  • Q shen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧