js进阶——什么是提升

embedded/2024/9/23 7:38:40/
webkit-tap-highlight-color: rgba(0, 0, 0, 0);">

JavaScript 中的提升(Hoisting)是一个重要的概念,它指的是 JavaScript 引擎在代码执行之前,会将变量和函数的声明提升到它们所在作用域的顶部。这意味着,即使变量或函数在代码中后面声明,它们的引用可以在声明之前进行。不过,不同类型的声明(如 varletconst 和函数声明)在提升中的行为有所不同。

1. 变量提升(Variable Hoisting)

  • 使用 var 声明的变量:在函数或全局作用域内,变量声明会被提升到作用域顶部。但值的初始化并不会被提升,因此在变量声明之前访问该变量会得到 undefined。这是因为只有声明部分被提升,赋值部分保留在原来的位置。
示例:
javascript">console.log(x); // undefined
var x = 5;
console.log(x); // 5

上述代码在内部被处理为:

javascript">var x;
console.log(x); // undefined
x = 5;
console.log(x); // 5

注意:变量 x 在第一次 console.log 输出时已经被声明了,但还没有赋值,所以返回 undefined

  • 使用 letconst 声明的变量:虽然它们的声明也会被提升,但它们在声明之前不可访问。访问时会抛出 ReferenceError,这段不能访问的时间区间被称为暂时性死区(Temporal Dead Zone, TDZ)。
示例:
javascript">console.log(y); // ReferenceError: Cannot access 'y' before initialization
let y = 10;

解释y 在代码执行过程中是存在的,但在到达 let 声明之前,它位于 TDZ 中,因此访问会抛出错误。

2. 函数提升(Function Hoisting)

  • 函数声明(Function Declaration):完整的函数声明会被提升到其作用域的顶部。这意味着即使函数调用出现在函数声明之前,JavaScript 依然能够正确执行代码。
示例:
javascript">sayHello(); // "Hello, world!"function sayHello() {console.log("Hello, world!");
}

上述代码在内部被处理为:

javascript">function sayHello() {console.log("Hello, world!");
}sayHello(); // "Hello, world!"
  • 函数表达式(Function Expression):与变量提升类似,函数表达式中的变量会被提升,但实际的函数定义不会被提升。这意味着,如果在定义之前调用函数表达式,访问到的是 undefined,而非函数。
示例:
javascript">sayHello(); // TypeError: sayHello is not a functionvar sayHello = function() {console.log("Hello, world!");
};

解释sayHello 被提升为一个未定义的变量,因此在调用时返回 undefined,而不是一个函数,这会导致 TypeError

3. 类提升(Class Hoisting)

  • 类声明(Class Declaration):与 letconst 类似,类声明也会被提升,但同样会存在暂时性死区,在声明之前访问类会抛出 ReferenceError
示例:
javascript">let instance = new MyClass(); // ReferenceError: Cannot access 'MyClass' before initializationclass MyClass {constructor() {this.name = "Example";}
}

解释:虽然类声明被提升,但在其实际定义之前无法使用。

4. 提升的执行顺序

提升的顺序基于作用域的类型和声明的种类:

  • 在全局作用域中,var 声明的变量和函数声明会被提升到全局的最顶端。
  • 函数内部的变量和函数会被提升到函数作用域的顶部。
  • letconst、类声明会在作用域中被提升,但不可在提升前访问(即它们会被放入 TDZ 中)。

5. 提升带来的常见问题

提升有时会导致代码行为不符合直觉,特别是对于新手来说,可能会导致难以理解的错误:

  • undefined 错误:因为 var 提升,未初始化的变量会返回 undefined 而不是抛出错误。
  • 函数与变量同名:当变量名和函数名相同时,变量声明会覆盖函数声明。
示例:
javascript">console.log(foo); // ƒ foo() {}var foo = 10;function foo() {console.log("I am a function");
}console.log(foo); // 10

在这里,foo 首先被提升为函数声明,所以第一次 console.log 输出函数定义。但由于 var foo = 10 声明的变量在作用域中覆盖了函数,第二次输出的是数值 10

6. 小结

  • 变量提升var 声明的变量会被提升到作用域顶部,但在初始化之前值为 undefinedletconst 也会被提升,但会产生暂时性死区(TDZ),使得在声明前访问它们会抛出错误。
  • 函数提升:函数声明会完整提升,而函数表达式的变量会提升但值不会提升。
  • 类提升:类声明也会提升,但会像 letconst 一样进入暂时性死区。

掌握提升机制有助于理解 JavaScript 的执行流程,写出更清晰的代码。


http://www.ppmy.cn/embedded/115479.html

相关文章

Hive之任务优化

Hive 是一个基于 Hadoop 的数据仓库工具,提供了 SQL-like 的查询语言来分析存储在 HDFS(Hadoop Distributed File System)上的大规模数据集。为了提高查询性能,Hive 提供了多种优化方法,涵盖不同层次的改进&#xff0c…

软件测试技术之 GPU 单元测试是什么!

1 背景 测试是开发的一个非常重要的方面,可以在很大程度上决定一个应用程序的命运。良好的测试可以在早期捕获导致应用程序崩溃的问题,但较差的测试往往总是导致故障和停机。 单元测试用于测试各个代码组件,并确保代码按照预期的方式工作。单…

证书学习(五)Java实现RSA、SM2证书颁发

目录 一、知识回顾1.1 X.509 证书1.2 X509Certificate 类二、代码实现2.1 Maven 依赖2.2 RSA 证书颁发1)PfxGenerateUtil 证书文件生成工具类2)CertDTO 证书中间类3)RSACertGenerateTest RSA证书生成测试类4)执行结果2.3 SM2 证书颁发1)SM2Utils 国密SM2算法工具类2)SM2C…

k8s的一些命令

kubectl get nodes :查看节点的状态 查看Pod的状态: kubectl get pod --all -namespacesPending,ContainerCreating,ImagePullBackOff都表明Pod没有就绪,Running才是就绪状态 查看Pod的具体情况: kubectl describe pod podnamek…

PDF转图片的思路思考

记录时间:2022年9月1日 PDF转图片库的使用和扩展 python有几个开源的免费的处理Pdf的库,甚至有的已经有很完善的功能了。我发挥一下自己的所学,看看能不能把它变为可用的一程序。 首先是了解PDF处理库PyMupdf,这个库得到路径之后普就可以对…

Vulkan 学习(8)---- vkImageView 创建

目录 OverView创建方法关键结构参考代码 OverView Vulkan 的图像视图(VkImageView) 用于描述如何访问 VkImage 对象以及访问图像的哪一部分, 图像视图定义了图像格式和访问方式,允许渲染管线和图像进行交互,无论是作为纹理,颜色附件或者深度…

Elastic 的 OpenTelemetry PHP 发行版简介

作者:Pawel Filipczak 宣布 OpenTelemetry PHP 的 Elastic 发行版的第一个 alpha 版本。在本篇博文中了解使用 OpenTelemetry 来检测 PHP 应用程序是多么简单。 我们很高兴推出 OpenTelemetry PHP 的 Elastic Distribution 的第一个 alpha 版本。在这篇文章中&…

洪涝洪水滑坡灾害数据集 灾害 2300张 带标注 voc yolo

洪涝洪水滑坡灾害数据集 灾害 2300张 带标注 voc yolo 洪涝洪水滑坡灾害数据集 数据集描述 该数据集是一个专门用于检测和识别洪涝、洪水和滑坡等自然灾害的数据集,旨在帮助研究人员和开发者训练和评估基于深度学习的目标检测模型。数据集涵盖了两种常见的自然灾害…