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

news2024/11/20 4:49:10

在这里插入图片描述

😁 作者简介:一名大四的学生,致力学习前端开发技术
⭐️个人主页:夜宵饽饽的主页
❔ 系列专栏: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中作用域的是什么?:从编译时其承担什么角色和查询作用域中的变量的角度解析作用域

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

带你摸透C语言相关内存函数

c语言中的小小白-CSDN博客c语言中的小小白关注算法,c,c语言,贪心算法,链表,mysql,动态规划,后端,线性回归,数据结构,排序算法领域.https://blog.csdn.net/bhbcdxb123?spm1001.2014.3001.5343 给大家分享一句我很喜欢我话: 知不足而奋进,望远山而前行&am…

vue2中如何实现添加一个空标签的效果,</>

前言&#xff1a; 众所周知&#xff0c;vue3突破了每一个vue文件中只能有一个根标签的限制&#xff0c;但是我们还有很多项目都是vue2的项目&#xff0c;如果让vue2中实现一个类似</>的效果呢&#xff0c;像react的16.2.0的版本之后&#xff0c;可以直接用<></&…

电脑音频显示红叉怎么办?这里提供四种方法

前言 如果你在系统托盘中看到音量图标上的红色X,则表示你无法使用音频设备。即使音频设备未被禁用,当你运行音频设备疑难解答时,仍然会看到此错误。 你的电脑将显示已安装高清音频设备,但当你将鼠标悬停在图标上时,它将显示未安装音频输出设备。这是一个非常奇怪的问题,…

C语言 指针(2)

文章目录 前言 一、数组名的理解 二、指针访问数组 三、一维数组传参的本质 四、冒泡排序 五、二级指针 六、指针数组 七、指针数组模拟二维数组 总结 前言 我们今天继续来了解指针的内容&#xff0c;让大家更加细致的理解到数组的含义 一、数组名的理解 之前我们在学习指针时…

王道OnlineJudge 14

题目 二叉树层次建树就是一层一层的建树&#xff0c;从左到右。随着纵向层次的深入&#xff0c;结点的数量变化规律为&#xff1a;1→2→4→8→16→32。 先画图&#xff0c;然后看图可闭眼写代码 右边为辅助队列&#xff0c;有多少个二叉树结点&#xff0c;就有多少个辅助队…

一个简单的Web UI自动化测试框架Java实现

&#x1f525; 交流讨论&#xff1a;欢迎加入我们一起学习&#xff01; &#x1f525; 资源分享&#xff1a;耗时200小时精选的「软件测试」资料包 &#x1f525; 教程推荐&#xff1a;火遍全网的《软件测试》教程 &#x1f4e2;欢迎点赞 &#x1f44d; 收藏 ⭐留言 &#x1…

口才教育:如何提升沟通技巧与表达能力

口才教育&#xff1a;如何提升沟通技巧与表达能力 口才教育在现代社会中扮演着越来越重要的角色。拥有良好的沟通技巧和表达能力对于个人的职业发展、人际交往乃至生活质量都至关重要。因此&#xff0c;如何有效地提升口才能力成为了许多人关注的焦点。本文将探讨口才教育的重…

java-可变参数

可变参数是什么&#xff1f; 可变参数就是指传入的参数个数是可变的&#xff0c;不是固定的 为什么要可变参数&#xff1f; 当我们要传入大量的形参时&#xff0c;我们就可以用到可变参数了 定义格式 数据类型...变量名; 例如int ...a; 可变参数的细节&#xff1a; &…

Vue2(五):收集表单数据、过滤器、内置指令和自定义指令

一、回顾 总结Vue监视数据 1.Vue监视数据的原理&#xff1a; 1.vue会监视data中所有层次的数据。 2.如何监测对象中的数据?通过setter实现监视&#xff0c;且要在new Vue时就传入要监测的数据。(1&#xff09;.对象中后追加的属性&#xff0c;Vue默认不做响应式处理(2&#…

java拷贝数组

package com.mohuanan.exercise;public class Exercise {public static void main(String[] args) {int[] arr {1, 2, 3, 4, 5, 6, 7, 8, 8}; //格式化快捷键 CTRL 加 Alt 加 L键// F1截图 F3贴图//调用 copyOfRangeint[] ints copyOfRange(arr, 3, 7);for (int i 0; i &l…

学习网络编程No.13【网络层IP协议理解】

引言&#xff1a; 北京时间&#xff1a;2024/3/5/8:38&#xff0c;早六加早八又是生不如死的一天&#xff0c;不过好在喝两口热水提口气手指还能跳动。当然起关键性作用的还是思维跟上了课程脑袋较为清晰&#xff0c;假如是听学校老师在哪里磨过来磨过去&#xff0c;那我倒头就…

三、HarmonyOS 应用开发入门之运行Hello World

目录 1、课程对象 1.1、有移动端开发经验 1.2、无移动端开发经验 1.3、对 HarmonyOS 感兴趣 2、DevEco Studio 的使用 2.1、DevEco Studio 的关键特性 智能代码编辑 低代码开发 多段双向实时预览 多端模拟仿真 2.2、安装配置 DevEco Studio 2.2.1、官网开发工具下载地…

Vue-Vben-Admin:中大型项目后台解决方案及如何实现页面反向传值

Vue-Vben-Admin&#xff1a;中大型项目后台解决方案及如何实现页面反向传值 摘要&#xff1a; Vue-Vben-Admin是一个基于Vue3.0、Vite、Ant-Design-Vue和TypeScript的开源项目&#xff0c;旨在为开发中大型项目提供一站式的解决方案。它涵盖了组件封装、实用工具、钩子函数、动…

Arduino ESP8266 SSD1306 硬件I2C+LittleFS存储GBK字库实现中文显示

Arduino ESP8266 SSD1306 硬件I2C+LittleFS存储GBK字库实现中文显示 📍相关篇《Arduino esp8266 软件I2C SSD1306 +LittleFS存储GBK字库实现中文显示》 🌼显示效果: ✨将部分函数重构,和上面相关篇的软件I2C通讯相关接口函数移植过来,除了汉字显示采用自己写的API函数外…

【数据结构取经之路】快速排序的非递归实现

概述 递归实现快速排序在一些场景下有栈溢出的风险&#xff0c;下面就谈谈如何用非递归的方法实现快速排序。 非递归实现的思想 递归实现与非递归实现快速排序的本质是一致的&#xff0c;效率并不会因为用了非递归实现而有所提升。递归实现快速排序的本质就在于通过递归&…

Linux系统目录结构详细介绍

目录 一、根目录&#xff08;/&#xff09; 二、/bin 三、/boot 四、/dev 1.设备文件类型&#xff1a; 2.常见设备文件&#xff1a; 五、/etc 六、/home 七、/root 八、/run 九、/sbin 十、 /tmp 十一、/usr 十二、/var Linux系统目录结构是一种层次化的文件系…

【数据结构】Set的使用

文章目录 一、Set的使用1.Set的常用方法&#xff1a;1.boolean add(E e)2.void clear()3.boolean contains(Object o)4.boolean remove(Object o)5.int size()6.boolean isEmpty()7.Object[] toArray()8.boolean containsAll(Collection<?> c)9.boolean addAll(Collecti…

leetcode 热题 100_删除链表的倒数第 N 个结点

题解一&#xff1a; 递归&#xff1a;利用递归栈逆向遍历链表&#xff0c;并用全局变量记录当前遍历的是倒数第几位节点&#xff0c;当遍历到待删节点的上一位节点时&#xff0c;node.nextnode.next.next删除待删节点。需要注意当删除的是头节点时&#xff0c;直接return head.…

zabbix 7.0编译部署教程

zabbix 7.0编译部署教程 2024-03-08 16:50乐维社区 zabbix7.0 alpha版本、beta版本已经陆续发布&#xff0c;Zabbix7.0 LTS版本发布时间也越来越近。据了解&#xff0c;新的版本在性能提升、架构优化等新功能方面有非常亮眼的表现&#xff0c;不少小伙伴对此也已经跃跃欲试。心…

Visual Basic6.0零基础教学(3)—焦点概念和深入学习属性

焦点概念和深入学习属性 文章目录 焦点概念和深入学习属性前言一、什么是焦点(Focus)?焦点的特点 二、窗体属性一、窗体的结构二、窗体的属性三、事件四、方法 一.控件属性一. 标签 Label二.文本框 TextBox2.常用事件 三.命令按钮事件 总结 前言 今天我们来继续学习VB中的属性…