〖大前端 - ES6篇②〗- let和const

  • 说明:该文属于 大前端全栈架构白宝书专栏,目前阶段免费如需要项目实战或者是体系化资源,文末名片加V!
  • 作者:哈哥撩编程,十余年工作经验, 从事过全栈研发、产品经理等工作,目前在公司担任研发部门CTO。
  • 荣誉:2022年度博客之星Top4、2023年度超级个体得主、谷歌与亚马逊开发者大会特约speaker全栈领域优质创作者

  • 🏆 白宝书系列
    • 🏅 启示录 - 攻城狮的自我修养
    • 🏅 Python全栈白宝书
    • 🏅 ChatGPT实践指南白宝书
    • 🏅 产品思维训练白宝书
    • 🏅 全域运营实战白宝书
    • 🏅 大前端全栈架构白宝书


文章目录

  • ⭐ let和const
  • ⭐ let、const和var的区别
  • ⭐ let、const的应用

⭐ let和const

letconst用来声明变量或声明常量

let代替var,声明变量

const,声明常量,const就是constant(恒定不变的)的缩写

示例代码:

// let 声明变量
let username = 'xiaoming';
// const 声明常量
const sex = '男';console.log(username, sex);   // xiaoming 男

变量和常量的区别: 变量初始化之后,还可以重新赋值;常量一旦初始化,就不能重新赋值了,否则会报错。这句话也可以反过来理解,可以重新赋值的就是变量,不可以重新赋值的就是常量

image-20231207100016930

我们初步了解了变量和常量的区别,但是我们仍然会有这样的疑问,为什么需要常量呢?什么时候需要声明常量?

  • 首先我们先来看,为什么需要常量?

​ 我们可以假设如果我们只有变量,在一些不能被修改的值一不小心被修改掉时,程序没有任何的提示和报错,比如一个人的性别被修改了也不会被发现:

image-20231211143332832

const就是为了那些一旦初始化就不希望重新赋值的情况设计的

使用const的注意事项:

  • 使用const声明常量,一旦声明,就必须立即初始化,不能留到以后赋值
  • const声明的引用类型的常量允许在不重新赋值的情况下修改它
  • 什么时候用const,什么时候用let?

​ 一眼就能看出来是变量的,就直接使用let就行了,比如for循环里的循环变量。

​ 如果不知道这个值会不会发生改变,可以先用const,当以后发现这个值需要改变时,再把const改成let

⭐ let、const和var的区别

let、const和var的区别可以总结为一下几点:

  • 重复声明
  • 变量提升
  • 暂时性死区
  • window对象的属性和方法(全局作用域中)
  • 块级作用域(最重要的区别)
varlet、const
重复声明允许不允许
变量提升不会
暂时性死区不存在存在
window对象的属性和方法(全局作用域中)会自动变成window对象的属性或方法不会自动变成window对象的属性或方法
块级作用域没有块级作用域有块级作用域

下面来我们敲几个demo来深入理解一下这些区别:

  • 重复声明:

    image-20231207102145945

  • 变量提升

    image-20231207102645970

​ 虽然var会自行进行变量提升使得程序不报错,但我们在编程时还是要养成先声明后使用的编程习惯。

  • 暂时性死区

    只要作用域存在let、const,它们声明的变量或常量就自动“绑定”这个作用域了,不再受外部作用域的影响

    image-20231207110824472

    暂时性死区和变量提升的影响很相似,只要我们养成了良好的编程习惯,就不会遇到暂时性死区的问题

  • window对象的属性和方法(全局作用域中)

​ 全局作用域中,var声明的变量,通过function声明函数,会自动变成winddow对象的属性或方法;let、const声明的就不会。

image-20231207111753429

  • 块级作用域(最重要的区别)

​ 首先,我们先要了解一下什么是作用域链

​ 我们的作用域有全局作用域函数作用域块级作用域

​ **块级作用域:**凡是带{}都是块级作用域,比如if(){}、for(){}、while(){}、do{}while()

​ **函数作用域:**function后面就是函数作用域,需要注意只有函数调用被的时候才会生成函数作用域,函数调用结束,函数作用域就销毁了

​ **全局作用域:**代码中的任何地方都能访问,其生命周期伴随着页面的生命周期

​ 而作用域链就是内层作用域->外层作用域->…->全局作用域,形成的一个“链条”。程序在寻找变量/常量时就会按照这个”作用域链“进行寻找,如果找到了就使用这个变量,如果找不到就继续找,最终找到全局作用域中,如果全局作用域中也没有定义这个变量,就会报错了。

image-20231208134249810

​ var没有块级作用域:

// var没有块级作用域
for (var i = 0; i < 2; i++) {// console.log(i);
}
console.log(i);     // 2

image-20231211134146195

let和const有块级作用域:

// let、const有块级作用域
for (let i = 0; i < 2; i++) {console.log(i);
}
console.log(i);     // 报错

image-20231211134721964

理解了“块级作用域“,我们再丰富一下上面的例子,使程序在寻找变量时形成一个“作用域链”:

let j = 10;
function func() {// let j = 100;for (let i = 0; i < 2; i++) {console.log(j);		// 10}
}
func();

image-20231211140233255

image-20231211140345415

⭐ let、const的应用

案例:

我们先来做一个小案例,页面上有三个按钮,分别玮0号按钮、1号按钮和2号按钮,我们想要实现的功能是,点击哪个按钮就在控制台打印出对应的编号,效果如下:

20231212_154230202312121543591

我们可以用for循环,给每个按钮添加鼠标点击事件监听,当鼠标点击时,在控制台输出按钮编号。如果没有学习ES6,按照我们的常规思路写出来的代码是这样的:

image-20231212164809813为什么会出现上面的问题呢?因为上面的代码存在作用域问题,我们知道var是没有块级作用域的,而函数只有在被调用的时候才会形成函数作用域,在上面的代码中,事件监听函数里显然是没有i变量的,根据作用域链,程序会继续往”外层“查找,因为var没有块级作用域,所以就直接找到了全局作用域,而在全局作用域中,i的值为3(因为程序运行后i的值就变成了3),所以不管点击哪个按钮,都会输出3。

上面代码中i的作用域的图示如下:

image-20231212172612621

那么如何来规避这个问题呢?我们可以把var替换成ES6中的let试试:

image-20231212165558640

很显然,替换成let后作用域的问题被解决了,我们就实现了案例题目要求的效果。

上面代码中i的作用域的图示如下:

image-20231212172911603

那么不用ES6就真的无法解决这个问题了吗?聪明的程序员们怎么可能被这个问题打倒呢?我们还记得在学习js时学到过”闭包“,闭包拥有记忆性,当闭包产生时,函数所处环境的状态会被始终保持在内存中,不会在外层函数调用后被自动清除。那么利用闭包的这个特性,我们尝试改造一下第一次编写的代码:

image-20231212170633560

上面代码中i的作用域的图示如下:

image-20231212173204868

了解闭包的会知道,闭包对性能是有”损伤“的,所以有了ES6,还是推荐大家使用ES6!

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

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

相关文章

ORACLE的 软 软 软 解析!

在海鲨数据库架构师精英群里,有位朋友说ORACLE 有 软软软解析. 就是把执行计划缓存在客户端里,从而避免去服务端找执行计划. 他给了个设置方法, Weblogic console->datasource->connectionPool Statement Cache Type >LRU Statement Cache Size100 CURSOR_NUMBER …

求满二叉树两个节点之间的最短距离

求满二叉树两个节点之间的最短距离 using System; using System.Collections.Generic; using System.Linq; using System.Text;namespace FirstSolver {internal class Program{static void Main(string[] args){BinaryTreeNode<int> root1 FullBinaryTree.CreateTree(1…

python实现基数排序

如果在给不同的整形数组排序的时候,一般会这样做,也就是先看最高位,如果最高位数值大的话也就意味着它的数值是最大的,而如果两个数字的最高位的数值是一样的,则继续比较次高位,这样依次去比较可以决定数字的排序。而对于基数排序来说,其思想是与以上的思想是不同的,基…

Node版本管理 - nvm

简介 nvm 允许用户在同一台电脑上安装并管理多个 Node.js 版本并支持快速切换&#xff0c;对于需要在不同的项目中使用不同版本的 Node.js 的开发者来说非常有用。 使用 下载安装后&#xff0c;以管理员身份打开windows控制台。 # 设置下载node安装包&#xff0c;和npm安装…

linux系统非关系型数据库redis常见问题以及好处

redis常见问题以及好处 redis常见问题缓存穿透概念解决方案布隆过滤器缓存空对象 缓存雪崩概念解决方案redis高可用限流降级数据预热 redis好处redis常见性能问题解决方案为redis加密 redis常见问题 缓存穿透 概念 缓存穿透的概念很简单&#xff0c;用户想要查询一个数据&am…

02-实现方法多值返回-pair与truple

在实际的项目开发中&#xff0c;我们经常会遇到返回多个值&#xff0c;通常我们使用Map对象、自定义Class对象等方式封装返回结果。但是这种方式&#xff0c;需要定义大量中间类&#xff0c;影响代码的整体质量。 spring 为我们提供了pair 双值与 triple 三值返回对象。 1、p…

二级C语言笔试6

(总分100,考试时间90分钟) 一、选择题 1. 设有以下语句&#xff1a; charx3&#xff0c;y6&#xff0c;z&#xff1b; zx^y&#xff1c;&#xff1c;2&#xff1b; 则z的二进制值是( )。 A. 00010100 B. 00011011 C. 00011100 D. 00011000 …

从Unity到Three.js(画线组件line)

JavaScript 0基础&#xff0c;只是照着官方文档临摹了下&#xff0c;之后有时间再进行细节学习和功能封装。 import * as THREE from three; //引入threejsconst renderer new THREE.WebGLRenderer();//创建渲染器 //设置渲染范围&#xff0c;当前撑满全屏,屏幕左上角是&…

C++类型转化cast from pointer to smaller type ‘int‘ loses information

代码如下 #include <iostream>int main() {int a 10;std::cout << (int)&a << std::endl;return 0; }编译 这段代码是要将地址转化成整数类型&#xff0c;但是在编译时编译器告诉我们这是错的&#xff0c;因为在C中&#xff0c;将指针转换为int类型的…

Spring IoC容器详解

版权声明 本文原创作者&#xff1a;谷哥的小弟作者博客地址&#xff1a;http://blog.csdn.net/lfdfhl 基本概念 Spring IoC容器是Spring框架的核心组件&#xff0c;它实现了控制反转&#xff08;Inversion of Control&#xff0c;IoC&#xff09;的设计原则。IoC是一种编程思…

【前端高频面试题--TypeScript篇】

&#x1f680; 作者 &#xff1a;“码上有前” &#x1f680; 文章简介 &#xff1a;前端高频面试题 &#x1f680; 欢迎小伙伴们 点赞&#x1f44d;、收藏⭐、留言&#x1f4ac; 高频前端面试题--Vue3.0篇 什么是TypeScript&#xff1f;TypeScript数据类型TypeScript中命名空…

最关键的十个图像特征

在计算机视觉中&#xff0c;图像特征是用来描述图像中视觉元素的一组属性&#xff0c;它们对于图像识别、分类、检测和分割等任务至关重要。以下是10个在计算机视觉中广泛使用的最重要的图像特征&#xff1a; 颜色直方图&#xff08;Color Histogram&#xff09;&#xff1a; 颜…

Days 27 ElfBoard 板 AltiumDesigner 相同电路快速布局布线

在进行设计开发的时候&#xff0c;总会遇到相同的电路&#xff0c;或者模块&#xff0c;这些电路可以使用相同的布局和走线&#xff0c;例如 DC-DC 电源、网口 PHY 电路部分。这类型的电路&#xff0c;我们可以采用AltiumDesigner 中的 Room 进行布局和布线的快速复制&#xff…

C#系列-并行处理+异步流(5)

一&#xff0c;C#并行处理 在C#中&#xff0c;并行处理指的是同时执行多个任务或操作&#xff0c;以利用多核或多处理器的优势&#xff0c;从而提高应用程序的性能。C#提供了多种工具和框架来帮助开发者实现并行处理。以下是一些在C#中实现并行处理的方法&#xff1a; Paralle…

VitePress-12-markdown中使用vue的语法

前言 VitePress 中&#xff0c;markdown文档最终都会转换成为 html文件&#xff0c;我们在访问的时候&#xff0c;也是直接访问的 xxx.html 文件。而且&#xff0c;markdown文档会被作为 [vue单文件] 进行处理&#xff0c;因此&#xff0c;我们我们可以在文档中使用 vue 语法&…

决策树之scikit-learn

实例 from sklearn.datasets import load_iris from sklearn import tree import matplotlib.pyplot as plt# Load iris dataset iris load_iris() X, y iris.data, iris.target# Fit the classifier clf tree.DecisionTreeClassifier() clf clf.fit(X, y)# Plot the deci…

Linux命令-batch命令(在系统不繁忙的时候执行定时任务)

说明 batch命令 用于在指定时间&#xff0c;当系统不繁忙时执行任务&#xff0c;用法与at相似。 语法 batch(选项)(参数)选项 -f&#xff1a;指定包含具体指令的任务文件&#xff1b; -q&#xff1a;指定新任务的队列名称&#xff1b; -m&#xff1a;任务执行完后向用户发送…

详细介绍Python网络编程模块

根据前面对网络分层棋型的介绍&#xff0c;我们知道实际的网络模型大致分为四层&#xff0c;这四层各有对应的网络协议提供支持&#xff0c; 网络层协议主要是 IP&#xff0c;它是所有互联网协议的基础&#xff0c;其中 ICMP&#xff08;Internet Control Message Protocol&…

烟雨要饭网带后台,附带搭建教程

直接上传访问即可&#xff0c;有安装向导&#xff0c;php环境不得低于7.0 后台地址/Admin&#xff0c;默认账号admin 默认密码123456 自带乞讨音乐&#xff0c;增加樱花特效

域内NAT:如何让内网client通过公网地址访问内网server?

第一步&#xff0c;实现任意公网用户访问内网server。按教育网规矩&#xff0c;公网过来的流量要访问校内网的server必须从教育专线&#xff08;路由器接口G0/0/1)进入。 第二步&#xff0c;实现内网主机通过公网地址210.43.2.3能够访问内网server192.168.1.2&#xff0c;图中①…