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'; // ReferenceError
  console.log(tmp); // ReferenceError

  let tmp; // TDZ结束
  console.log(tmp); // undefined

  tmp = 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; // 这里改变了外层函数的x
    console.log(x); // 输出2
  }
  console.log(x); // 输出2,因为var变量提升了且被覆盖
}

// let 示例
function letExample() {
  let y = 1;
  if (true) {
    let y = 2; // 这里创建了一个新的块级作用域变量y
    console.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旨在让函数声明遵循块级作用域规则,但由于兼容性问题,最好在块级作用域中使用函数表达式以确保代码的可预测性和兼容性。

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

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

相关文章

x64dbg中类似于*.exe+地址偏移

在CE和xdb中,形如*.exe数字偏移形式的地址被称为模块地址,CE附加到进程后点击查看内存,显示如下图 这种地址学名叫做模块地址,在x64dbg中显示如下图: CE中可以关闭,从而显示绝对的虚拟地址,如下…

Hive-URL解析函数

Hive-URL解析函数 1.实际工作需求 2.URL的基本组成 3.Hive中的Url解析函数 parse_url函数 parse_url_tuple函数

VScode通过ssh远程连接服务器被拒绝:permission denied, please try again

使用场景: 使用windows系统下的vscode远程连接服务器的linux系统,终端提示permission denied, please try again,但是使用cmd是可以远程登录的。 解决办法: 前提条件windows端的vscode安装了ssh远程连接的相关插件Remote - SSH,…

红米Turbo3小米平板6SPro澎湃OS系统强解BL锁-跳小米社区绑定-刷ROOT权限

红米Turbo3小米平板6SPro这2款设备都出厂为澎湃OS系统,官方提供都是小米社区申请解锁权限,然后自己答题解锁,门槛非常高,想要玩机root的用户,都在堵在门外。还在这目前这两款机型官方并没有加入强制验证,在…

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

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

机器人种类分析

2000年前,机器人主要应用于工业生产,俗称工业机器人,由示教器操控,帮助工厂释放劳动力,此时的机器人并没有太多智能而言,完全按照人类的命令执行动作,更加关注电气层面的驱动器、伺服电机、减速…

Springboot集成Netflix-ribbon、Consul实现负载均衡调用-09

Consul简介 Consul是一个开源的服务发现和配置管理工具,具有跨平台、运行高效等特点。它由HashiCorp公司开发,并使用Go语言编写。Consul主要用于实现分布式系统中的服务发现、健康检查、键值存储等功能。 核心功能 服务发现:Consul通过DNS…

JavaScript百炼成仙自学笔记——13

函数七重关之六(“new”一个函数) 看个代码: function hello(){console.log(this); } 1、this:也是JavaScript中的一个关键字,永远指向当前函数的调用者 解释一下,有两层意思: ①this要嘛不出现&#…

基于SSM的“环卫工管理平台”的设计与实现(源码+数据库+文档+PPT)

基于SSM的“环卫工管理平台”的设计与实现(源码数据库文档PPT) 开发语言:Java 数据库:MySQL 技术:SSM 工具:IDEA/Ecilpse、Navicat、Maven 系统展示 系统总体设计图 注册 首页 后台登录 后台页面 环卫工管理 摘…

mac安装 php7.1/apache

1. 安装php 7.1 brew tap shivammathur/php 查看可安装版本 brew search php 安装指定版本(禅道适用PHP运行环境(7.0/7.1/7.2版本)) brew install php7.1 环境配置 vim ~/.zshrc export PATH"/usr/local/opt/php7.1/bin:$PATH" export …

使用Postman进行接口测试---解析postman页面

一、Postman 是一款流行的 API 测试工具,它提供了丰富的功能来帮助开发者测试和调试 API。以下是 Postman 页面上的主要功能及其含义和作用: 1. 请求详情(Request Details) : - 方法(Method&#xff0…

【读论文】Gaussian Grouping: Segment and Edit Anything in 3D Scenes

Gaussian Grouping: Segment and Edit Anything in 3D Scenes 文章目录 Gaussian Grouping: Segment and Edit Anything in 3D Scenes1. What2. Why3. How3.1 Anything Mask Input and Consistency3.2 3D Gaussian Rendering and Grouping3.3 Downstream: Local Gaussian Editi…

第二篇【AI与传奇开心果系列】Python的AI技术点库案例示例:详解AI工业应用算法原理

AI与传奇开心果系列博文 系列博文目录Python的AI技术点库案例示例系列 博文目录前言一、AI工业应用算法原理介绍二、机器学习在工业领域的应用算法示例代码三、深度学习算法在工业领域应用示例代码四、强化学习在工业领域应用示例代码五、自然语言处理在工业领域应用示例代码六…

C语言 变量的作用域

今天 我们来说变量的作用域和存储类型 每种事物 都有自己作用的范围限制 例如 汽车只能在路上跑 轮船只能在海洋 飞机只能通行于天空 函数的参数 也只有在函数被调用过程中分配内存资源 函数执行结束 空间也会被立即释放 这也说明了 行参变量只有在函数内才有效 离开了该函数 …

【JavaEE】博客系统(前端页面设计)

文章目录 一、预期效果二、实现博客列表页 一、预期效果 二、实现博客列表页 实现导航栏 编辑 blog_list.html, 创建导航栏的 html 代码. 导航栏里面包含 logo, 标题, 以及一些按钮(跳转链接). 为了实现左右排列, 在 logo 和 按钮 之间加一个 spacer 作为占位器. <!-- 导航…

初次查询大数据信用报告,需要注意哪些问题?

随着大数据的普及&#xff0c;基于大数据技术的大数据信用也变得越来越重要&#xff0c;比如在申贷之前&#xff0c;不少地方都会查询申贷人的大数据信用&#xff0c;作为风险控制的必要手段&#xff0c;那对于初次查询大数据信用报告的人来说&#xff0c;需要注意哪些问题呢?…

引领AI数据标注新纪元:景联文科技为智能未来筑基

在人工智能蓬勃发展的今天&#xff0c;数据如同燃料&#xff0c;驱动着每一次技术飞跃。在这场智能革命的浪潮中&#xff0c;景联文科技凭借其深厚的专业实力与前瞻性的战略眼光&#xff0c;正站在行业前沿&#xff0c;为全球的人工智能企业提供坚实的数据支撑。 全国布局&…

vscode的git插件使用教程

虽然git的命令我没有滚瓜烂熟&#xff0c;但vscode的git插件是尊嘟很好用啊&#xff0c;都被我用烂了。在网上看见一个讲的很不错的插件教程。借鉴一下。并在一些地方用块引用进行了补充说明&#xff01; 跳过了vscode安装过程。 克隆GitHub中的存储库&#xff1a; 1、复制Gi…

python3有serial库吗

一、概述 pyserial模块封装了对串口的访问。 二、特性 在支持的平台上有统一的接口。 通过python属性访问串口设置。 支持不同的字节大小、停止位、校验位和流控设置。 可以有或者没有接收超时。 类似文件的API&#xff0c;例如read和write&#xff0c;也支持readline等…

探案录 | KingbaseES+SqlSugar为医疗用户排忧解难

在2024年的初春&#xff0c;某大型三甲医院的CT预约系统上线测试&#xff0c;如同新芽破土&#xff0c;充满了希望与活力。然而&#xff0c;仅仅两天后&#xff0c;一个技术难题如同迷雾中的幽灵&#xff0c;悄然出现&#xff1a;The connection pool has been exhausted…… 福…