let命令

  • let 命令
    • let 与 var
      • 二者区别:
        • 作用域不同
        • 变量提升(Hoisting)
        • 临时性死区
        • 重复声明
      • 联系:
      • 举例说明:
    • 块级作用域
      • 块级作用域的关键字
      • 使用 var(无块级作用域)
      • 使用 let(块级作用域)
      • 使用 const(块级作用域且常量)
    • 块级作用域与函数声明

1. let 命令

ES6 新增了 let 命令,用来声明变量。它的用法类似于 var ,但是所
声明的变量,只在 let 命令所在的代码块内有效。

{let a = 10;var b = 1;
}
a // ReferenceError: a is not defined.
b // 1

上面代码在代码块之中,分别用 let 和 var 声明了两个变量。然后在
代码块之外调用这两个变量,结果 let 声明的变量报错, var 声明的
变量返回了正确的值。

这表明, let 声明的变量只在它所在的代码块有效。

1.1. let 与 var

letvar 都是用来在 JavaScript 中声明变量的关键字,但它们之间存在一些关键区别:

1.1.1. 二者区别:
1.1.1.1. 作用域不同
  • var 声明的变量具有函数作用域全局作用域

如果在函数内部声明,它只在该函数内部可见;如果在函数外部声明,则在整个脚本中都可见,成为全局变量(在浏览器环境下,全局变量会成为 window 对象的属性)。

  • let 声明的变量具有块级作用域

这意味着变量只在它声明的那个代码块(例如,if 语句、for 循环或者一对大括号 {} 内)内有效。

1.1.1.2. 变量提升(Hoisting)
  • var 声明的变量会存在变量提升现象,即使声明在代码执行之后,变量也会被提升至作用域顶部,但在赋值前其值为 undefined

  • let 不会发生变量提升,如果在声明前访问 let 变量,会导致引用错误(ReferenceError)。

1.1.1.3. 临时性死区

当使用 letconst 声明变量时,在声明之前访问这些变量会触发错误,这个区域被称为临时死区。

这是为了防止变量在声明前的不确定状态,提高代码的可预测性。

if (true) {console.log(temp); // 报错,temp在TDZ中let temp = "ES6";
}

只要块级作用域内存在 let 命令,它所声明的变量就“绑定”(binding)
这个区域,不再受外部的影响。

var tmp = 123;
if (true) {
tmp = 'abc'; // ReferenceError
let tmp;
}

上面代码中,存在全局变量 tmp ,但是块级作用域内 let 又声明了一
个局部变量 tmp ,导致后者绑定这个块级作用域,所以在 let 声明变
量前,对 tmp 赋值会报错。

ES6明确规定,如果区块中存在 let 和 const 命令,这个区块对这些
命令声明的变量,从一开始就形成了封闭作用域。凡是在声明之前就使
用这些变量,就会报错。

总之,在代码块内,使用 let 命令声明变量之前,该变量都是不可用
的。这在语法上,称为“暂时性死区”(temporal dead zone,简称
TDZ)。

if (true) {// TDZ开始tmp = 'abc'; // ReferenceErrorconsole.log(tmp); // ReferenceErrorlet tmp; // TDZ结束console.log(tmp); // undefinedtmp = 123;console.log(tmp); // 123
}

上面代码中,在 let 命令声明变量 tmp 之前,都属于变量 tmp 的“死
区”。

暂时性死区的本质就是,只要一进入当前作用域,所要使用的变量就已经存在了,但是不可获取,只有等到声明变量的那一行代码出现,才可以获取和使用该变量

1.1.1.4. 重复声明
  • 使用 var 可以在同一作用域内重复声明同一个变量,后面的声明会覆盖前面的声明。

  • let 不允许在同一作用域内重复声明同一个变量,尝试这样做会导致语法错误。

1.1.2. 联系:
  • 它们都是用于变量声明的关键词。
  • 在基本的变量赋值和访问操作上,两者的行为是类似的,一旦声明并赋值后,都可以用来存储数据。
1.1.3. 举例说明:
// var 示例
function varExample() {var x = 1;if (true) {var x = 2; // 这里改变了外层函数的xconsole.log(x); // 输出2}console.log(x); // 输出2,因为var变量提升了且被覆盖
}// let 示例
function letExample() {let y = 1;if (true) {let y = 2; // 这里创建了一个新的块级作用域变量yconsole.log(y); // 输出2}console.log(y); // 输出1,因为let有块级作用域
}varExample(); // 调用函数演示var行为
letExample(); // 调用函数演示let行为

在这个例子中,varExample 函数展示了使用 var 时变量提升以及在相同作用域内重复声明导致的变量覆盖现象。

letExample 函数则展示了 let 如何在块级作用域内创建独立的变量,避免了变量覆盖的问题。

ES6 规定暂时性死区和 let 、 const 语句不出现变量提升,主要是为
减少运行时错误,防止在变量声明前就使用这个变量,从而导致意料
之外的行为。这样的错误在 ES5 是很常见的,现在有了这种规定,避免
此类错误就很容易了。

1.2. 块级作用域

ES5 只有全局作用域和函数作用域,没有块级作用域。

ES6(ECMAScript 2015)引入了块级作用域,这是一种新的变量作用域规则,它允许变量在代码块(通常是一对大括号 {} 内)内声明和使用,超出这个块之后,这些变量就会被销毁或不再可见。

这与ES5中的作用域规则不同,ES5中只有全局作用域和函数作用域,没有块级作用域的概念。

实例一

var tmp = new Date();
function f() {console.log(tmp);if (false) {var tmp = 'hello world';}
}
f(); // undefined

实例二

var tmp = new Date();
function f() {console.log(tmp); 
}
f(); // Mon May 06 2024 09:44:26 GMT+0800 (中国标准时间)

实例一代码的原意是, if 代码块的外部使用外层的 tmp 变量,内部使
用内层的 tmp 变量。但是,函数 f 执行后,输出结果为 undefined

原因在于变量提升,导致内层的 tmp 变量覆盖了外层的 tmp 变量。

1.2.1. 块级作用域的关键字
  • let: 用于声明一个块级作用域的变量,它可以重复声明,但在同一作用域内不能重复初始化。
  • const: 用于声明一个块级作用域的常量,一旦赋值不能改变,也不能重新声明。
1.2.2. 使用 var(无块级作用域)

在ES5中,即使变量在某个代码块内声明,它也会被提升到包含它的函数作用域或全局作用域中。

var x = 1;
if (true) {var x = 2; // 这里的x会覆盖外层的x
}
console.log(x); // 输出2
1.2.3. 使用 let(块级作用域)

使用 let 声明的变量只在声明它的块内有效。

let y = 1;
if (true) {let y = 2; // 这个y只在这个if块内有效
}
console.log(y); // 输出1,外层的y不受影响
1.2.4. 使用 const(块级作用域且常量)

const 声明的变量同样遵循块级作用域,而且声明后其值不能被重新赋值。

if (true) {const z = 3; // z是一个常量,只能在此if块内访问// z = 4; // 这里会报错,尝试修改常量值
}
// console.log(z); // 这里也会报错,z在块外不可见

1.3. 块级作用域与函数声明

函数能不能在块级作用域之中声明?这是一个相当令人混淆的问题。

ES5 规定,函数只能在顶层作用域和函数作用域之中声明,不能在块级作用域声明。

// 情况一
if (true) {function f() {}
}
// 情况二
try {function f() {}
} catch(e) {
// ...
}

上面两种函数声明,根据 ES5 的规定都是非法的。

在ES6(ECMAScript 2015)之前,JavaScript只有全局作用域和函数作用域。这意味着在函数外部声明的变量是全局变量,在函数内部声明的变量则是局部变量,仅在该函数内部可见。然而,对于if语句、for循环等代码块内部,并没有自己的作用域。

ES6引入了块级作用域,主要通过letconst关键字实现,这使得开发者可以在任何块(例如if语句、for循环的花括号内)内声明变量,这些变量的作用域仅限于该块。

关于函数声明在块级作用域中的行为,ES6规范试图明确函数声明应当具有块级作用域特性,即在块内声明的函数只应在该块内可访问。

理论上,这样的函数声明应该类似于使用let声明的变量,只在声明它们的块中可见。例如:

{function sayHello() {console.log("Hello");}sayHello(); // 此处可以调用
}
// sayHello(); // 理论上此处应该报错,因为sayHello只在上面的块内可见

但实际上,由于历史遗留原因和浏览器兼容性问题,早期的ES6实现中,函数声明在块级作用域的行为并不统一。

一些环境(特别是某些浏览器)可能仍然会将块级函数声明提升到包含块的顶部,或者有其他非标准行为。

因此,在实际开发中,为了避免潜在的问题,推荐在块级作用域内使用函数表达式而非函数声明:

{const sayHello = function() {console.log("Hello");};sayHello(); // 正确使用函数表达式
}
// sayHello(); // 这里依然会报错,因为sayHello是块级作用域内的函数表达式

总结来说,虽然ES6旨在让函数声明遵循块级作用域规则,但由于兼容性问题,最好在块级作用域中使用函数表达式以确保代码的可预测性和兼容性。

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

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

相关文章

JavaScript手写专题——图片懒加载、滚动节流、防抖手写

图片懒加载场景:在一些图片量比较大的网站(比如电商网站首页,或者团购网站、小游戏首页等),如果我们尝试在用户打开页面的时候,就把所有的图片资源加载完毕,那么很可能会造成白屏、卡顿等现象&a…

ICode国际青少年编程竞赛- Python-2级训练场-range函数

ICode国际青少年编程竞赛- Python-2级训练场-range函数 1、 for i in range(4):Dev.turnLeft()Dev.step(i 1)2、 for i in range(4):Spaceship.step(i 1)Spaceship.turnRight()3、 for i in range(4):Spaceship.step(i 1)Dev.step(2)Dev.step(-2)4、 for i in range(1, 5)…

【深度学习】【Lora训练2】StabelDiffusion,Lora训练过程,秋叶包,Linux,SDXL Lora训练

文章目录 一、如何为图片打标1.1. 打标工具1.1.1. 秋叶中使用的WD1.41.1.2. 使用BLIP21.1.3. 用哪一种 二、 Lora训练数据的要求2.1 图片要求2.2 图片的打标要求 三、 Lora的其他问题qa1qa2qa3qa4qa5 四、 对图片的处理细节4.1. 图片尺寸问题4.2. 图片内容选取问题4.3. 什么是一…

2024年3月份宠物行业线上市场数据分析:市场呈现出精细化、品质化趋势

近些年来,养宠物的家庭越来越多,宠物经济也逐渐衍生开来。宠物经济主要是围绕宠物产生的一整条产业链,包括宠物食品、宠物家居、宠物美容和最近火起来的宠物保险等多个领域。目前随着居民人均收入的提高,宠物市场也得到稳步发展。…

【Qt 学习笔记】Qt常用控件 | 输入类控件 | Slider的使用及说明

博客主页:Duck Bro 博客主页系列专栏:Qt 专栏关注博主,后期持续更新系列文章如果有错误感谢请大家批评指出,及时修改感谢大家点赞👍收藏⭐评论✍ Qt常用控件 | 输入类控件 | Slider的使用及说明 文章编号:…

Java | Leetcode Java题解之第80题删除有序数组中的重复项II

题目&#xff1a; 题解&#xff1a; class Solution {public int removeDuplicates(int[] nums) {int n nums.length;if (n < 2) {return n;}int slow 2, fast 2;while (fast < n) {if (nums[slow - 2] ! nums[fast]) {nums[slow] nums[fast];slow;}fast;}return sl…

查看pytorch与cuda对应版本

查看cuda版本 打开cmd,输入nvidia-smi&#xff0c;即可可以看到cuda的版本了 2. pytorch与cuda版本对应关系 可以参考这篇文章&#xff0c;写的非常详细&#xff1a;https://blog.csdn.net/FL1768317420/article/details/134769203

5. 分布式链路追踪TracingFilter改造增强设计

前言 在4. 分布式链路追踪客户端工具包Starter设计一文中&#xff0c;我们实现了基础的Starter包&#xff0c;里面提供了我们自己定义的Servlet过滤器和RestTemplate拦截器&#xff0c;其中Servlet过滤器叫做HoneyTracingFilter&#xff0c;仅提供了提取SpanContext&#xff0…

WebRTC 客户端状态机

WebRTC 客户端状态机 WebRTC 客户端状态机客户端状态机客户端加入流程图客户端离开流程图端到端连接的基本流程 WebRTC 客户端状态机 客户端状态机 首先我们来看一下客户端的一个状态机&#xff0c;客户端与服务器直接通过信令的一个交互之后自然而然的形成一个状态机&#x…

读天才与算法:人脑与AI的数学思维笔记23_人工智能讲故事

1. 伟大的自动语法分析器 1.1. 思维呆板机械的阿道夫奈普&#xff08;Adolphe Knipe&#xff09;一直想成为一名作家&#xff0c;可是他写出来的东西既迂腐又无趣 1.2. 后来&#xff0c;灵光乍现&#xff0c;他得到了一个启示&#xff1a;语言遵循语法规则&#xff0c;这规则…

【连连国际注册_登录安全分析报告】

连连国际注册/登录安全分析报告 前言 由于网站注册入口容易被黑客攻击&#xff0c;存在如下安全问题&#xff1a; 暴力破解密码&#xff0c;造成用户信息泄露短信盗刷的安全问题&#xff0c;影响业务及导致用户投诉带来经济损失&#xff0c;尤其是后付费客户&#xff0c;风险巨…

OPC :快速上手

本系列为OPC技术的快速上以及持续研究和技术实战专栏&#xff0c;将不定期更新。 本章节提供OPC系列技术博文的快速导航。 《OPC服务器简介和入门介绍》 《物联网平台如何为OPC服务器创造新生命力》 《OPC服务器开发之WtOPCSvr——开发文档&#xff08;1&#xff09;》 《OPC服…

何为基差?股指期货的升水和贴水又怎么理解?

基差是一个金融术语&#xff0c;它指的是现货价格和期货价格之间的差额。在股指期货市场中&#xff0c;现货就是指实际的股票指数&#xff0c;而期货则是基于这个指数未来某个时间点的价格预期。基差可以是正的或负的&#xff0c;具体取决于期货价格是高于还是低于现货价格。 1…

每日一题7:Pandas-重命名列

一、每日一题 编写一个解决方案&#xff0c;按以下方式重命名列&#xff1a; id 重命名为 student_idfirst 重命名为 first_namelast 重命名为 last_nameage 重命名为 age_in_years 返回结果格式如下示例所示。 解答&#xff1a; import pandas as pddef renameColumns(studen…

《2024年AI安全报告》:AIML工具使用量飙升594.82%

人工智能&#xff08;AI&#xff09;不仅仅是一种开拓性的创新技术&#xff0c;甚至已经成为一种常态&#xff0c;企业正在工程、IT营销、财务、客户服务等领域迅速采用AI和机器学习&#xff08;ML&#xff09;工具。但与此同时&#xff0c;他们必须平衡AI工具带来的诸多风险&a…

ESP32引脚入门指南(三):从理论到实践(Touch Pin)

引言 ESP32作为物联网领域的明星微控制器&#xff0c;不仅以其强大的网络通信能力著称&#xff0c;还内置了丰富的外设资源&#xff0c;其中就包括电容式触摸传感&#xff08;Capacitive Touch&#xff09;功能。本文旨在深入浅出地介绍ESP32的Touch引脚&#xff0c;带你了解其…

15-LINUX--线程的创建与同步

一.线程 1.线程的概念 线程是进程内部的一条执行序列或执行路径&#xff0c;一个进程可以包含多条线程。 2.线程的三种实现方式 ◼ 内核级线程&#xff1a;由内核创建&#xff0c;创建开销大&#xff0c;内核能感知到线程的存在 ◼ 用户级线程&#xff1a;线程的创建有用户空…

刷题第3天(简单题):LeetCode206--反转链表--双指针法

LeetCode206&#xff1a;给你单链表的头节点 head &#xff0c;请你反转链表&#xff0c;并返回反转后的链表。 示例 1&#xff1a; 输入&#xff1a;head [1,2,3,4,5] 输出&#xff1a;[5,4,3,2,1]示例 2&#xff1a; 输入&#xff1a;head [1,2] 输出&#xff1a;[2,1]示例…

五一超级课堂---Llama3-Tutorial(Llama 3 超级课堂)---第三节llama 3图片理解能力微调(xtuner+llava版)

课程文档&#xff1a; https://github.com/SmartFlowAI/Llama3-Tutorial 课程视频&#xff1a; https://space.bilibili.com/3546636263360696/channel/collectiondetail?sid2892740&spm_id_from333.788.0.0 操作平台&#xff1a; https://studio.intern-ai.org.cn/consol…

自动镭雕机价格是多少?

自动镭雕机是一种高精度、高效率的激光雕刻设备&#xff0c;广泛应用于手机、电脑、玻璃等产品表面的图案雕刻。那么&#xff0c;自动镭雕机多少钱一台呢&#xff1f;本文将为您详细解析各种因素对自动镭雕机价格的影响。 一、影响自动镭雕机价格的因素 1. 品牌和质量 自动镭…