【变量提升】关于JavaScript变量提升的理解,它导致了什么问题?

在这里插入图片描述

😁 作者简介:一名大四的学生,致力学习前端开发技术
⭐️个人主页:夜宵饽饽的主页
❔ 系列专栏:JavaScript小贴士
👐学习格言:成功不是终点,失败也并非末日,最重要的是继续前进的勇气

​🔥​前言:

这是我在整理JavaScript中觉得比较重要的基础知识,有关变量提升的,希望可以帮助到大家,欢迎大家的补充和纠正

文章目录

    • 11 关于JavaScript变量提升,它导致了什么问题
      • 一、前言:
      • 二、变量提升的原因
      • 三、函数声明的细节
      • 四、为什么要变量提升
      • 五、变量提升的缺点。
    • 六、 最后:

11 关于JavaScript变量提升,它导致了什么问题

一、前言:

😀在介绍变量提升之前,大家可以先看一段有意思的代码:

//第一种情况
a=2
var a;
console.log(a)


//第二种情况
console.log(b)
var b=3

❓这两种情况的代码,大家可以猜一下最后会输出什么呢?

👉答案是:

  • 第一种情况会输出2
  • 第二种情况会输出undefined

这种输出是不是出乎意料,那么到底发生了什么呢?我们接下来一起来看看今天的”主角“概念,变量提升。

⭐什么是变量提升:变量和函数声明从它们在代码中出现的位置被提升”移动“到最上面

二、变量提升的原因

JavaScript代码在执行之前引擎会首先对其进行编译,编译阶段的一部分工作就是找到所有声明,并使用合适的作用域将它们关联起来,正是因为这个机制,包含变量和函数在内的所有声明都会在任何代码被执行前首先被处理

当我们看到一个变量赋值的语句时:

var a=2

可能会认为这是一个声明,但是JavaScript实际上会将其看成两个声明:var a;和a = 2。

第一定义声明是在编译阶段进行的,第二个渎职声明会被留着原地等待执行阶段,所以代码声明和赋值是在不同阶段的。

那么现在我们来看我们上面的代码,实际会以如下形式进行处理

//第一种情况
var a
a=2
console.log(a)

//第二种情况
var b
console.log(b)
b=2

所以可以得知**代码是先声明后赋值,**只有声明本身会被提升,而赋值或其他运行逻辑会留在原地

三、函数声明的细节

看完变量之后,我们来了解一下函数声明,会有一些注意点

请看如下代码:

foo()

function foo(){
  console.log(a) //undefined
  var a=2
}

上面代码中,函数是先调用后声明的,按自上到下的逻辑理解,这样显然是不合理的,但是这样依然可以正常执行,因为函数声明也会提升。而且在函数作用域内部的变量也会被提升,提升到函数作用域的最上方

每个函数作用域都会进行提升操作,提升到函数作用域的最上方

所以上面的代码可以理解为以下这种形式

function foo(){
  var a;
  console.log(a)
  a=2
}

foo()

注意,函数声明会提升,但是函数表达式不会被提升,切记!切记!

⭐函数声明和变量声明都会被提升,那么是哪一个先被提升,或者说当存在函数声明和变量声明,是谁在最上方

🌱函数会首先被提升,然后才是变量

四、为什么要变量提升

变量提升主要有两个原因:

  • 提高性能
  • 容错率更好
  1. 提高性能:在js代码执行之前,会进行语法检查和编译,而且这一操作只进行一次,如果没有这一步每次代码的执行都必须重新解析一遍代码,而且在解析的过程中,还会为函数生成预编译代码,那么当代码没有改变时,会直接使用预编译中的变量和函数,所以当代码执行时就不需要进行编译了,性能当然会提高。
  2. 容错率更好:虽然我们应该避免先赋值再声明,我们应该有先声明再赋值的好习惯,但是再JavaScript代码执行的过程中,这种先赋值再声明的错误写法也是可以正确执行的。

五、变量提升的缺点。

变量提升虽然有一些优点,但是他也会造成一定的问题,可以来看以下代码:

//第三情况
var tmp=new Date()

function fn(){
    console.log(tmp)

    if(false){
        var tmp='老秀才'
    }
}

fn()

在这个函数,原本要打印出外层的tmp变量,但是因为变量提升问题,导致内层的变量被提升到函数内部作用域的最顶层,相当覆盖了外层的tmp,所以输出结果undefined

六、 最后:

🌼下面推荐的一篇文章可以补充和扩展文章中涉及的知识点 😃

  • 【js作用域】JavaScript中作用域的是什么?:从编译时其承担什么角色和查询作用域中的变量的角度解析作用域

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/438648.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

JumpServer 简介安装

目录 1、概念介绍 JumpServer 概述 JumpServer 功能 JumpServer 组件 JumpServer 架构 2、前置安装 环境要求 安装 ELRepo 库 更新内核 设置 grub2 安装 Python 配置 Python 虚拟环境 3、安装 Jumpserver Core 组件 下载安装 替换客户端组件 安装 Python 依赖库…

力扣刷题

文章目录 1. 双指针1.1 两数之和1.2 三数之和1.3 盛最多水的容器1.4 接雨水 2. 字串2.1 滑动窗口最大值 3. 动态规划4. 多维动态规划4.1 最长回文字串 1. 双指针 1.1 两数之和 思路:因为是有序数组, 1.2 三数之和 题目要求不能重复 思路:三…

FPGA 串口多字节发送,串口回环测试

串口接收 串口帧 设计文件 timescale 1ns / 1ps // // Company: // Engineer: // // Create Date: 2023/01/12 23:11:28 // Design Name: // Module Name: UART_Byte_Rx // Project Name: // Target Devices: // Tool Versions: // Description: // // Dependencies…

python螺旋数字矩阵

python螺旋数字矩阵 给出数字个数n&#xff0c;输出1-n (0<n ≤999)和行数m (0<m ≤ 999)&#xff0c;从左上角的1开始&#xff0c;按照顺时针螺旋向内写方式&#xff0c;依次写出2,3.….&#xff0c;最终形成一个m行矩阵。 1.每行数字的个数一样多 2.列的数量尽可能少 3…

01-环境搭建、SpringCloud微服务-黑马头条

环境搭建、SpringCloud微服务(注册发现、服务调用、网关) 1)课程对比 2)项目概述 2.1)能让你收获什么 2.2)项目课程大纲 2.3)项目概述 随着智能手机的普及&#xff0c;人们更加习惯于通过手机来看新闻。由于生活节奏的加快&#xff0c;很多人只能利用碎片时间来获取信息&…

【netty系列-02】深入理解socket本质和BIO底层实现

Netty系列整体栏目 内容链接地址【一】深入理解网络通信基本原理和tcp/ip协议https://zhenghuisheng.blog.csdn.net/article/details/136359640【二】深入理解Socket本质和BIOhttps://zhenghuisheng.blog.csdn.net/article/details/136549478 深入理解socket本质和bio底层实现 …

【RT-DETR有效改进】全新的SOATA轻量化下采样操作ADown(轻量又涨点,附手撕结构图)

一、本文介绍 本文给大家带来的改进机制是利用2024/02/21号最新发布的YOLOv9其中提出的ADown模块来改进我们的Conv模块,其中YOLOv9针对于这个模块并没有介绍,只是在其项目文件中用到了,我将其整理出来用于我们的RT-DETR的项目,经过实验我发现该卷积模块(作为下采样模块)…

蓝桥杯备赛之二分专题

常用的算法二分模板 1. 在数组a[]中找大于等于x的第一个数的下标 //int ans lower_bound(a, a n, x) - a //相当于下方 int l 0, r n - 1; while(l < r) {int mid l r >> 1;if(a[mid] > x) r mid;else l mid 1; } cout << r;2. 在数组a[]中找大于…

间隔5分钟执行1次Python脚本设置步骤 —— 定时执行专家

《定时执行专家》是一款制作精良、功能强大、毫秒精度、专业级的定时任务执行软件&#xff0c;用于在 Windows 系统上定时执行各种任务&#xff0c;包括执行脚本或程序。 下面是使用 "定时执行专家" 软件设置定时执行 Python 脚本的步骤&#xff1a; 步骤 1: 设置 P…

图遍历算法

图的遍历算法有两种&#xff1a;深度优先遍历、广度优先遍历算法。 深度优先遍历算法就是从起始结点开始&#xff0c;只要有相邻且未被访问的结点就要直接进行访问&#xff0c;直到最后不能向下遍历为止&#xff0c;再回溯寻找下一个策略。 广度优先遍历算法&#xff0c;就是从…

像SpringBoot一样使用Flask - 1.新建一个Flask项目

感谢各位对上一篇文章的喜爱&#xff0c;从事10年开发&#xff0c;希望借此可以简单实操下从SpringBoot到Flask的转型&#xff0c;少走一点弯路&#xff0c;多花一点时间在处理实际问题。 一、用pycharmConda新建一个Flask项目 二、得到一个Flask项目 三、运行起来访问下&#…

Spring Boot中实现图片上传功能的两种策略

&#x1f31f; 前言 欢迎来到我的技术小宇宙&#xff01;&#x1f30c; 这里不仅是我记录技术点滴的后花园&#xff0c;也是我分享学习心得和项目经验的乐园。&#x1f4da; 无论你是技术小白还是资深大牛&#xff0c;这里总有一些内容能触动你的好奇心。&#x1f50d; &#x…

selenium也能过某数、5s盾..

文章转载于&#xff1a;selenium也能过某数、5s盾… 直接安装: pip install undetected_chromedriver运行代码&#xff1a; import undetected_chromedriver as uc import timedriver uc.Chrome(executable_pathrC:\Users\chromedriver.exe,version_main111) driver.get(网…

单链表的实现(数据结构)

本篇博客主要是单链表&#xff08;无头单项不循环&#xff09;的实现的代码分享 说明&#xff1a;因为此单链表无头&#xff08;哨兵位&#xff09;&#xff0c;可以说成没有初始化也可以说初始化时没有一个有效地址作为单链表的起始地址 例如下面代码中的plist NULL。 所以在…

DEYO: DETR with YOLO for End-to-End Object Detection论文翻译

DEYO&#xff1a;DETR与YOLO用于端到端目标检测 摘要 DETR的训练范式在很大程度上取决于在ImageNet数据集上预训练其骨干。然而&#xff0c;由图像分类任务和一对一匹配策略提供的有限监督信号导致DETR的预训练不充分的颈部。此外&#xff0c;在训练的早期阶段匹配的不稳定性会…

iStoreOS系统内安装HomeAssistant服务

iStoreOS系统内安装HomeAssistant服务 1. HomeAssistant服务 HomeAssistant是一款基于Python的开源智能家居系统&#xff0c;简称HA。 HomeAssistant可以方便地连接各种外部设备&#xff0c;如智能设备、摄像头、邮件、短消息和云服务等&#xff0c;其成熟的可连接组件有近千…

【重温设计模式】迭代器模式及其Java示例

迭代器模式的介绍 在编程领域&#xff0c;迭代器模式是一种常见的设计模式&#xff0c;它提供了一种方法&#xff0c;使得我们可以顺序访问一个集合对象中的各个元素&#xff0c;而又无需暴露该对象的内部表示。你可以把它想象成一本书&#xff0c;你不需要知道这本书是怎么印…

最佳牛围栏(二分 + 前缀和)

最佳牛围栏 原题链接&#xff1a;https://www.acwing.com/problem/content/104/ 题目 思路 我们发现若是枚举答案的话&#xff0c;那么我们判断是否存在一个平均值大于等于mid&#xff0c;如果最优解是x&#xff0c;那么mid < x的时候&#xff0c;必然可以找到一段&#x…

二十七 超级数据查看器 讲解稿 APP的用途 能做什么

二十七 超级数据查看器 讲解稿 APP的用途 能做什么 ​ 点击此处 访问B站 以新页面观看教学视频 点击此处 访问豌豆荚 下载APP 讲解稿全文: 大家好&#xff0c;今天我们讲一下超级数据查看器 的用途 也就是讲软件有什么用&#xff0c;能做什么&#xff0c;应用场景&#xff0…

mongo和redis的数据备份和还原

redis 安装 Redis安装和基本使用&#xff08;windows版&#xff09; - 知乎 window环境下Redis7服务器的安装和运行_redis7 windows-CSDN博客 备份数据 Redis SAVE 命令用于创建当前数据库的备份。 该命令将在 redis 安装目录中创建dump.rdb文件 查询路径 CONFIG GET dir…