[JavaScript]何为变量提升?

【版权声明】未经博主同意,谢绝转载!(请尊重原创,博主保留追究权)
https://blog.csdn.net/m0_69908381/article/details/139742129
出自【进步*于辰的博客】

关于编译与解释,详述可查阅博文《[Java]知识点》中的【编译与解释】一栏。
参考笔记二,P43.3、P46.1、P9.3。

文章目录

  • 附言
  • 1、介绍
  • 2、解答
  • 3、一种特殊情况
  • 最后

附言

你在阅读本篇文章时,会看到一些名词,如:函数作用域,也就是由 var 声明的变量的作用域的名称,它是我根据我的理解自定义的。后来我了解到,JS中似乎并没有这个概念,对应的概念好像是“词法作用域”。

我暂未系统地学习JS,故无法详细地为你说明这个概念。当然,尽管我的用词可能不对,但就目前,这有助于我的学习理解。

如果你想进一步地学习这方面的知识,推荐一篇博文《JavaScript执行机制:变量提升、作用域链、词法作用域、块级作用域、闭包和this》(转发)。

1、介绍

什么是“变量提升?

“变量提升”是指在解释时,解释器先扫描整个JS脚本,将所有声明(包括变量和函数)移动到作用域顶端的机制,其本质就是声明与定义不同步的错觉。

var 与 let 具有相同的变量提升机制,故经变量提升后(“解释”后)的脚本相同。

PS:大家可能不明其意,往下看。

先说说两种修饰符声明变量的作用域的定义:

  1. var:作用域的“上界”是变量声明处“往上”的第一个函数花括号({),故也称为“函数作用域”。var 允许重复声明和定义。
  2. let:作用域的“上界”是变量声明处“往上”的第一个花括号({).,故也称为“块级作用域”。let 不允许重复声明和定义(同一作用域)。

let 与 var 不同的是,let 声明的变量在定义之前,存在“暂时性死区”,

示例:

console.log(str)
let str = 1

输出结果:
在这里插入图片描述
因为示例代码经“变量提升”后:

let str
console.log(str)
str = 1

这就是“暂时性死区”,在定义前访问或赋值会报错。如:let str是声明,let str = 1是定义。

2、解答

1:如何理解“函数的变量提升优先于变量?”(PS:一些资料中可能会这样阐述)

事实上,之前由于我的JS功底不够扎实,也误解了这句话,以为是这样:

console.log(b)
var a = 1
var b = function() {return 2
}

经变量提升后:

var b
var a
console.log(b);// undefined
a = 1
b = function() {return 2
}

如果真的如我之前这般理解,无意义,并且也理解错误。

那么,“函数的变量提升优先于变量”这句话到底是什么意思?我从博文《JavaScript执行前的秘书——预编译》(转发)中取经得知,如下:

console.log(b)
var a = 1
function b() {return 2
}

经变量提升后:

function b() {return 2
}
var a
console.log(b);// [Function: b]
a = 1

所以,我之前是把var b = function() {}的形式误解为"函数声明”,实际上,这也是“变量声明”,只是变量值定义为函数而已。

最后,引用一段“取经”博文中的阐述:
在这里插入图片描述

2:如何解释“let 不允许重复声明和定义”?

我们先来看由 var 修饰的情况,示例:

var a = 1
var a = 2

经变量提升后:

var a
a = 1
a = 2

也就是:变量提升会将重复声明进行覆盖

再来看 let 的情况。如果两个同名的变量都由 let 修饰,报错,这是 let 的特性。大家疑惑的多是这种情况:

var a = 1
let a = 2

先解答:也会报错。为什么?这涉及到一个细节:

var 的变量提升的优先级高于 let。

也就是说,经变量提升后:

var a
let a
a = 1
a = 2

这种情况 let 同样不允许,故报错。

稍作修改:

let a = 1
var a = 2

这种情况与上述完全相同,故也不允许。

3、一种特殊情况

在上文中,我们说到,这种情况不允许:

var a = 1
let a = 2

那么,请问下面这种情况能正常执行吗?

var a = 1
{----------------------Alet a = 2
}

要解决这个问题,就要研究 var 与 let 的作用域了,大家还记得我在上文中所述的它们的作用域的定义吗?结论:

第一个a的作用域是“全局”,而第二个a的作用域是 A 处的代码块。

因此,两个a的作用域不同,故不报错。

再给大家抛出一个问题:这样会报错吗?

let a = 1
{var a = 2
}

PS:相信大家看到这里,已经对 var 和 let 有了足够的掌握,这个问题就交由大家思考了。

最后

为大家补充两个结论:

  1. var 是ES5的语法,let 是ES6的语法。
  2. 定义变量时可以不用 var 或 let 修饰(即直接a = 1),那么 var 与 let 的作用是什么?var 与 let 定义 / 决定了变量的作用域。因此,定义变量时如果不用 var 或 let 修饰,就不存在“变量提升”,则在定义前访问或赋值将直接报错。

还有,const也会“变量提升”,如let一般,具有块级作用域。

本文完结。

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

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

相关文章

泛微开发修炼之旅--17基于Ecology短信平台,实现后端自定义二开短信发送方案及代码示例

文章链接:17基于Ecology短信平台,实现后端自定义二开短信发送方案及代码示例

《山西教育》教学版是什么级别的刊物?

《山西教育》教学版是什么级别的刊物? 《山西教育(教学版)》创刊于1956年,是由山西教育报刊社主办的教学刊物。山西省一级期刊,是“宣传教育政策,关注教育热点,传播先进经验,提供教改资讯”的权威性期刊&a…

[深度学习]--分类问题的排查错误的流程

原因复现: 原生的.pt 好使, 转化后的 CoreML不好使, 分类有问题。 yolov8 格式的支持情况 Format Argument Suffix CPU GPU 0 PyTorch - .pt True True 1 Tor…

HQChart实战教程73-仿tradingview指标MACD

HQChart实战教程73-仿tradingview指标MACD MACD![在这里插入图片描述](https://img-blog.csdnimg.cn/direct/84d180b5620940f6b9fe08c6f10eb0f3.png)麦语法脚本实心MACD指标脚本效果 空心MACD指标脚本效果图 自定义指标添加到系统指标里HQChart插件源码地址 MACD tradingview中…

在Windows环境下设置定时任务(任务计划程序)(Python)

文章目录 前言一、准备执行的test.py文件二、准备test.bat批处理文件(系统环境变量)三、设置定时任务(任务计划程序) 前言 计划任务是系统的常见功能,利用任务计划功能,可以将任何脚本、程序或文档安排在某…

自研一套带双向认证的Android通用网络库

当前,许多网络库基于Retrofit或OkHttp开发,但实际项目中常需要定制化,并且需要添加类似双向认证等安全功能。这意味着每个项目都可能需要二次开发。那么,有没有一种通用的封装方式,可以满足大多数项目需求?…

基于Spring框架的应用:构建企业级应用的业务逻辑层

引言 在现代软件开发中,尤其是企业级应用程序开发中,选择合适的框架至关重要。Spring框架,作为一个轻量级的Java开发框架,旨在解决企业级应用开发中的耦合问题。本文将深入探讨Spring框架的核心组件之一——业务逻辑层&#xff0…

怎么制作酒店订房功能

在这个快节奏的时代,每一次旅行都如同一次心灵的远航。而酒店,作为旅途中的“避风港”,它的选择显得尤为重要。你是否曾在忙碌的行程中,为了寻找一家心仪的酒店而焦头烂额?是否曾在深夜的街头,为了找到一个…

美式动漫效果PS图层样式

对于追求独特艺术风格和创意的摄影师和设计师来说,一款能够轻松将照片转化为卡通效果的Photoshop模板无疑是一个强大的工具。这款由专业团队精心打造的模板,特别注重于美式动漫风格的呈现,让您的照片瞬间拥有生动且充满魅力的动漫色彩。 模板…

elementPlus+vite 定制化主题色

导读:在使用elementPlus组件库的过程中,可以自定义样式(比如主题色)修改默认样式,导入定制化样式文件进行样式覆盖 1、新建样式文件 1.1 新建 styles/element/index.scss 自定义项目主题色 // 重写项目主题色 forwa…

odoo 定时备份

odoo10 定时备份,每天备份一次,每七天删除一次 #!/bin/bash# vars BACKUP_DIR~/odoo_backups ODOO_DATABASEdb1 ADMIN_PASSWORDsuperadmin_passwd# create a backup directory mkdir -p ${BACKUP_DIR}# create a backup curl -X POST \-F "master_…

2台nginx只需配置一台,另外一台直接生效

配置文件更新与应用重启脚本使用指南 需求说明 需要一个脚本来完成以下任务: 修改 /data/THS/conf/httpserver.conf 文件后重启本地应用。将 /data/THS/conf/httpserver.conf 文件拷贝到远程服务器 192.142.8.82 的 /data/THS/conf/ 目录下,覆盖远程的…

Plonky3和Binius中的Brakedown多项式承诺协议解析及优化(3)

3.2 Expander Graph and Linear-Time Encodable Linear Code 线性时间编码是线性纠错码的一种,核心是扩展图(Expander Graph),如下图所示: Figure 3 Expander Graph Expander Graph是一种具有强连通性的稀疏图&#…

【C语言】位运算符

前言 C语言中给我们提供了6个位运算符,包括2个移位运算符和其他4个位运算符(按位取反、按位与、按位异或,以及按位或)。它们可以用于对整数数据进行位运算,现在就让我们来了解一下吧! 移位运算符 移位运算…

Python关闭exe文件

Python关闭exe文件的代码详解 在Python中,我们可以使用一些代码来关闭正在运行的exe文件。在本篇文章中,我们将介绍如何使用Python代码来关闭exe文件,并提供示例代码进行演示。 关闭exe文件的原理 在深入讨论关闭exe文件之前,让我…

Python 引入中文py文件

目录 背景 思路 importlib介绍 使用方法 1.导入内置库 importlib.util 2.创建模块规格对象 spec importlib.util.spec_from_file_location("example_module", "example.py") 3.创建模块对象 module importlib.util.module_from_spec(spec) …

MyBatis基础教程

文章目录 一、MyBatis基本使用1.1简介1.2搭建MyBatis环境1.2.1安装MyBatis1.2.2创建MyBatis核心配置文件1.2.3创建mapper接口1.2.4创建MyBatis映射文件1.2.5实现增加功能 1.3整合log4j1.4修改与删除功能1.5查询功能1.5.1查询单个实体类对象1.5.2查询所有用户信息 二、核心配置文…

“Redis中的持久化:深入理解RDB与AOF机制“

目录 # 概念 1. RDB持久化 1.1 备份是如何执行的(RDB过程) 1.2 配置文件信息 1.3 RDB持久化操作 1.4 RDB优势 1.5 RDB劣势 1.6 RDB做备份 2. AOF持久化 2.1 AOF开启及使用 2.2 异常恢复 2.3 配置文件操作 2.4 AOF持久化流程 2.5 优点 2.6…

Service的作用是什么?

在Android开发中,Service是一个重要的组件,它允许应用在后台执行长时间运行的操作,同时不向用户显示界面。以下是关于Service的作用的详细描述,包括技术难点、面试官关注点、回答吸引力和代码举例。 一、技术难点 生命周期管理&…

利用Elasticsearch提升Java应用的搜索能力

引言: 在数据驱动的时代,能够快速地处理和分析大量数据变得至关重要。Elasticsearch不仅提供全文搜索功能,还支持复杂的数据分析,是现代应用中不可或缺的工具之一。 什么是Elasticsearch? Elasticsearch是一个高度可…