第一章前端开发ES6基础
认识ES6
概述
ES6表示ECMAScript规范的第六版,正式名称为ECMAScript 2015,ECMAScript是由ECMA国际标准组织制定的一项脚本语言的标准规范化,引入了许多新特性和语法。
其中包括箭头函数、let和const声明、类、模板字符串、解构赋值、参数默认值、展开操作符、Promise等等。这些新的特性让JavaScript更加现代化、灵活和易于使用。
ES6可以在大多数现代浏览器中使用,也可以通过Babel等工具转换为ES5的语法以支持更旧的浏览器。除了浏览器之外,ES6还可以在Node.js环境下使用。总的来说,ES6已经成为现代JavaScript开发的标准,被广泛应用于各种前端和后端项目中。
ES6的目的是使JavaScript语言适应更复杂的应用,实现代码库之间的共享,并迭代维护新版本,成为企业级开发语言
关系
ECMAScript是JavaScript语言的国际标准
JavaScript是实现ECMAScript标准的脚本语言
关键字
let关键字
- let关键字声明的变量只有所处的块级作用域有效,而不是在整个函数作用域内有效
块级作用域是指花括号{}包含的代码块,比如for循环或if语句中的代码块。其作用场景有两个方面:
- 防止代码块内层变量覆盖外层变量
<script>if (true) {let a = 10;console.log(a); //输出结果:10}console.log(a); //报错,a未定义
</script>
这段代码中使用了let关键字来声明变量a。let关键字声明的变量具有块级作用域,即只在当前代码块内有效。在这个例子中,a只在if语句的代码块中定义,因此在代码块外部访问变量a时会报错,提示变量未定义。
具体地说,当执行到console.log(a)的时候,因为a只存在于if语句的块级作用域中,所以在块级作用域外部并不存在变量a,导致此处的console.log(a)执行时出现了引用错误
- 防止循环变量变成全局变量
<script>for (let i = 0; i < 2; i++) {}console.log(i); //报错,i未定义
</script>
这段代码使用了let关键字来声明变量i。在JavaScript中,let关键字声明的变量具有块级作用域,因此在代码块外部无法访问该变量。在这个例子中,for循环中的变量i只存在于for循环的代码块中,当循环结束后,变量i的作用域也就结束了,外部无法再访问该变量。因此,在代码块外部访问变量i时,会报错提示变量未定义。
具体来说,当执行到console.log(i)的时候,因为i只存在于for循环的块级作用域中,所以在块级作用域外部并不存在变量i,导致此处的console.log(i)执行时出现了引用错误。
提示:let关键字的好处是避免变量污染全局作用域,提高代码可维护性,也可以避免var声明变量时存在的变量提升问题,即在变量声明之前使用变量会导致不可预测的结果。
function foo() {let x = 1; //只在 example 函数内部有效if (true) {let x = 2; // 不同于外部的 x,只在 if 语句块内有效console.log(x); //输出2}console.log(x); //输出1
}
在if语句的块级作用域内声明的变量x只在该作用域内有效,不会影响到外部作用域的变量x,因此输出结果为2和1。
- let关键字声明的变量不存在变量提升
在JavaScript中使用var关键字声明的变量时,变量可以先使用后声明,即变量的声明语句会被提前至作用域的顶部,但是变量的赋值语句仍然保留在原来的位置。这种现象称为变量提升。
而使用let关键字声明的变量则不会发生变量提升,变量的声明和赋值必须在同一代码块内完成,否则会报错。这意味着,在使用let关键字声明变量之前,该变量的上下文中必须不存在对该变量的引用或调用,否则会抛出ReferenceError异常。
下面是一个简单的案例:
<script>console.log(count); // 报错:count未定义let count = 0;
</script>
在上述例子中,使用let关键字声明了一个名为count的变量,并将其初始化为0。但是,在第一行调用count时,由于使用let关键字声明的变量不存在变量提升,count变量未被定义,代码会抛出引用错误。
- let关键字声明的变量具有暂时性死区特性
暂时性死区是指在代码块中(例如,函数、循环或块语句中)使用let或const声明变量时,变量在声明前无法被访问。在该变量声明之前的任何访问都将导致“ReferenceError”。
具体来说只要块级作用域内存在let命令,它所声明的变量就“绑定”(binding)了这个区域,不再受外部的影响。这意味着在变量声明前,该变量是不能被访问或调用的。
以下是一个例子,展示了let关键字声明的变量具有暂时性死区特性:
<script>
let x = 10;
if (true) {console.log(x); // 报错:x未定义let x = 20;
}
<script>
在这个例子中,变量x被定义为10,并在if语句中使用let关键字重新声明并初始化为20。但是,在if语句的块级作用域内,x被绑定了该区域,因此变量x在声明之前被访问会导致引用错误。这就是暂时性死区的特性
const关键字
- const关键字声明常量的只有所处的块级作用域有效,而不是在整个函数作用域内有效
下面是一个简单的例子,演示了使用const关键字声明常量的作用域仅限于所在的块级作用域(即大括号内)。
function example() {const a = 1;if (true) {const a = 2;console.log(a); // 输出2}console.log(a); // 输出1
}example();
在这个例子中,我们在函数作用域内声明了一个常量a,并在if语句的块级作用域内重新声明a。由于const声明的常量的作用域仅限于所在的块级作用域(即大括号内),所以第一个console.log语句输出2,而第二个console.log语句输出1。
- const关键字声明常量时必须赋值
使用 const 声明常量时必须同时进行赋值,否则会抛出一个 SyntaxError 错误。这是因为 const 声明的变量是常量,一旦被声明,就不能再被修改。以下是一个使用 const 声明常量并赋值的例子:
const PI = 3.14159;
console.log(PI); //输出 3.14159
- const关键字声明常量赋值后常量的值不能修改
使用 const 声明的常量的值不能被修改。以下是一个简单的案例:
const PI = 3.14159;
PI = 3.14; // 尝试修改常量的值
console.log(PI); // 会抛出一个 TypeError 错误
在上述代码中,我们尝试将 PI 的值修改为 3.14,但运行该代码时会抛出一个 TypeError 错误,因为我们不能修改 const 声明的常量的值。
提示:var、let、const关键字之间的区别:都是用于声明变量或常量,其中 var 是 ES5 中声明变量的方式,而 let 和 const 是 ES6 中引入的声明变量和常量的方式。 var 和 let 声明的变量可以被重新赋值,而 const 声明的常量不可被重新赋值。
解构赋值
概述
解构表示对数据结构进行分解,赋值是指将某一数值赋给变量的过程
优点是编写的代码简洁易读、语义清晰、方便从数组或对象中提取值
数组的解构赋值
数组的解构赋值就是将数组中的值提取出来,赋给另外的变量
数组的解构赋值是一种方便的方式,可以让我们从数组中获取单个值或多个值,然后将它们赋值给变量。它的基本语法如下:
let arr = [1, 2, 3, 4];
let [a, b, c, d] = arr;
console.log(a); // 1
console.log(b); // 2
console.log(c); // 3
console.log(d); // 4//注意在浏览器控制台中输出上述代码的结果,有可能会报错,可以把let关键字去掉再运行
在上面的例子中,我们定义了一个数组 arr,然后使用数组解构赋值的方式将数组中的元素赋值给变量 a、b、c、d。这样我们就可以通过变量来获取数组中的元素了。
对象的解构赋值
对象的解构赋值允许使用变量的名字匹配对象的属性,如果匹配成功就将对象中属性的值赋给变量
对象的解构赋值是一种方便的方式,可以让我们从对象中获取单个属性或多个属性,并将它们赋值给变量。它的基本语法如下:
let obj = { x: 1, y: 2 };
let { x, y } = obj;
console.log(x); // 1
console.log(y); // 2
在上面的例子中,我们定义了一个对象 obj,然后使用对象解构赋值的方式将对象中的属性赋值给变量 x、y。这样我们就可以通过变量来获取对象中的属性了。
箭头函数
概述
箭头函数是ES6中引入的一种新的函数表达式,它的语法更加简洁,同时还具有一些特殊的功能
用于简化函数的定义语法,有自已的特殊语法,接收一定数量的参数,并在其封闭的作用域的上下文(即定义的函数或其他代码)中操作
语法
基本定义语法:
() => { }
上述语法中() => { } 是 ES6 中的箭头函数语法,它表示一个没有参数的箭头函数,并且函数体为空。具体来说,箭头函数是一种更加简洁的函数表达式,可以用一个箭头(=>)连接函数参数和函数体。例如:
// 常规函数表达式
function add(a, b) {return a + b;
}// 箭头函数表达式
const add = (a, b) => a + b;
特点
-
箭头函数是匿名函数,因此需要通过变量或常量来引用函数。例如:
// 声明一个箭头函数并赋值给变量 add const add = (a, b) => a + b;// 使用 add 函数计算 1 + 2 的值 const result = add(1, 2); // 3 -
箭头函数可以省略函数体中的花括号
{ },如果函数体只有一条语句,那么可以直接返回这条语句的值。例如:// 等价于 function (a, b) { return a + b; } const add = (a, b) => a + b;// 等价于 function (num) { return num % 2 === 0; } const isEven = num => num % 2 === 0; - 箭头函数的参数列表可以省略小括号
(),但是只有当参数个数为1时可以省略。例如:
// 等价于 function (num) { return num * num; }
const square = num => num * num;// 等价于 function () { console.log('Hello, world!'); }
const logHello = () => console.log('Hello, world!');
- 箭头函数没有自己的
this值,它会继承外层作用域的this值,因此在箭头函数中使用this时,它会指向外层作用域的this,而不是箭头函数自己的this。例如:const obj = {name: 'Alice',greet: function() {setTimeout(() => {console.log(`Hello, ${this.name}!`);}, 1000);}, };obj.greet(); // "Hello, Alice!" (1秒钟后输出)在上面的代码中,我们定义了一个对象
obj,它有一个名为greet的方法,方法中使用了箭头函数来打印一条欢迎语句。由于箭头函数继承了greet方法的this值,因此在箭头函数中使用this.name时,它会指向obj的name属性,即输出Hello, Alice!
扩展:在ES6之前,JavaScript中的关键字this指向的对象是在运行时基于函数的执行环境绑定的,在全局函数中,关键字this指向的是window;当函数被作为某个对象的方法调用时,this关键字指向那个对象
剩余参数
概述
在 JavaScript 中,剩余参数(Rest Parameters)是一种特殊的函数参数,它允许我们在函数定义中传入任意数量的参数,而这些参数都会被自动组织成一个数组,并作为剩余参数传递给该函数。在函数体中,我们可以像处理普通数组一样使用剩余参数,也就是通过下标来获取数组元素,或者使用数组的一些方法对其进行操作。
语法
function funcName(...args) {// function body
}
上述代码中的 ...args 表示任意数量的参数,它们会被组织成一个数组 args。可以通过数组下标 args[0]、args[1] 等来引用这些参数。
除了在函数定义时使用剩余参数外,我们还可以在调用函数时使用剩余参数来传入一个数组,这时候需要在数组前面加上三个点 ...,以表示将该数组转换成一系列的参数。例如:
function funcName(arg1, arg2, ...restArgs) {// function body
}let arr = [1, 2, 3, 4, 5];
funcName(...arr);
上述代码中的 ...restArgs 表示剩余参数,它会包含数组 arr 中除了前两个元素以外的所有元素,也就是 3、4、5。由于我们在调用函数时使用了 ...arr,因此这个数组会被转换成一系列的参数,即 arg1 为 1,arg2 为 2,restArgs 则为剩余的参数。
组合使用
剩余参数和解构赋值可以很好地组合在一起使用,以便更方便地访问剩余参数中的元素。
例如,我们可以在函数定义中使用解构赋值来获取剩余参数中的第一个和第二个元素,然后在函数体内对它们进行操作。示例代码如下:
function funcName(...[first, second, ...rest]) {console.log("first:", first); // 输出第一个元素console.log("second:", second); // 输出第二个元素console.log("rest:", rest); // 输出剩余的元素
}funcName(1, 2, 3, 4, 5);
在上述代码中,剩余参数 rest 包含了除了前两个参数以外的所有元素,而我们通过解构赋值分别获取了剩余参数中的第一个和第二个元素,分别赋值给了变量 first 和 second。
这样,我们就可以在函数体内直接使用变量 first 和 second 来操作这两个元素,而无需通过下标来访问它们。同时,函数调用代码也变得更加简洁,只需要传入一系列的参数即可,无需手动创建一个数组。
项目
下面是一个利用关键字、解构赋值、箭头函数和剩余参数来实现一个简单的项目的示例。该项目可以将用户输入的一组数字求和,并在控制台输出结果。
// 定义求和函数
const sum = (...numbers) => {let total = 0; //使用关键字 `let` 声明变量 `total`for (let number of numbers) { //使用 `for...of` 循环遍历可迭代对象 `numbers` 中的元素。total += number; //累加语句,将 `number` 的值加到 `total` 中}return total; //函数返回值,将计算得到的 `total` 作为函数返回值
}; //箭头函数的定义方式,使用剩余参数语法 `...` 来接收任意数量的参数。// 监听用户输入
const inputValues = () => {let input = prompt("请输入一组数字,用逗号分隔:"); //使用 `prompt` 方法显示一个提示框,并接收用户输入的一组数字。let values = input.split(",").map((value) => parseInt(value.trim())); //使用 `split` 方法将用户输入的数字字符串按照逗号分隔成为一个数组,然后使用 `map` 方法对数组中的每个元素进行处理,去掉空格并将其转换为整数类型。let total = sum(...values); 。。使用剩余参数语法 `...`,将数组 `values` 展开成为一个个数字拆分,作为参数传递给 `sum` 函数,并将计算结果赋值给变量 `total`console.log(`结果:${total}`); //:使用模板字符串的语法,将计算得到的结果输出到控制台中。
10. `inputValues();`:调用函数开始监听用户输入并计算结果。
};inputValues(); // 调用函数开始监听输入并计算结果
上述代码中,我们首先定义了一个求和函数 sum,使用了箭头函数和剩余参数的特性,用于接收用户输入的一组数字,并计算它们的和。接下来,我们定义了一个监听用户输入的函数 inputValues,其中使用了关键字 let、解构赋值和数组的 map 方法,将用户输入的一组逗号分隔的数字字符串转换成了数组,然后将数组传递给 sum 函数计算结果。最后,我们在函数内部使用了 console.log 方法将结果输出到控制台。
在调用 inputValues 函数时,用户将会收到一个提示框,要求输入一组数字,用逗号分隔。用户输入完成后,我们将监听到输入并将其转换成数字数组,然后求和,并将结果输出到控制台。
相关文章:
第一章前端开发ES6基础
认识ES6 概述 ES6表示ECMAScript规范的第六版,正式名称为ECMAScript 2015,ECMAScript是由ECMA国际标准组织制定的一项脚本语言的标准规范化,引入了许多新特性和语法。 其中包括箭头函数、let和const声明、类、模板字符串、解构赋值、参数默…...
【算法练习Day30】无重叠区间 划分字母区间合并区间
📝个人主页:Sherry的成长之路 🏠学习社区:Sherry的成长之路(个人社区) 📖专栏链接:练题 🎯长路漫漫浩浩,万事皆有期待 文章目录 无重叠区间划分字母区间合并…...
Linux部署Redis哨兵集群 一主两从三哨兵(这里使用Redis6,其它版本类似)
目录 一、哨兵集群架构介绍二、下载安装Redis2.1、选择需要安装的Redis版本2.2、下载并解压Redis2.3、编译安装Redis 三、搭建Redis一主两从集群3.1、准备配置文件3.1.1、准备主节点6379配置文件3.1.2、准备从节点6380配置文件3.1.3、准备从节点6381配置文件 3.2、启动Redis主从…...
VR结合|山海鲸虚拟展厅解决方案
方案背景 虚拟现实技术是另一项革命性的创新,它可以将用户带入一个完全虚拟的环境中。借助VR头盔和控制器,用户可以亲临虚拟现实中,与数字世界互动,仿佛置身于其中。 山海鲸根据用户实际需求变化将数字孪生与虚拟现实技术相结合…...
记一次企业微信的(CorpID)和密钥(Secret)泄漏的利用案例
文章目录 一、介绍二、利用过程1、获取AccessToken2、获取企业微信接口IP段3、获取企业微信回调IP段4、通过部门ID,查看返回的ID5、通过部门ID,查看用户列表6、通过便利ID,发现用户信息泄露,可以进行提交报告7、通过添加接口,添加企业账号8、登陆企业账号进行测试三、参考…...
使用Selenium和Java编写爬虫程序
以下是一个使用Selenium和Java编写的音频爬虫程序,该程序使用了proxy的代码。请注意,这个示例需要在IDE中运行,并且可能需要根据您的系统和需求进行调整。 import java.io.IOException; import java.util.List; import java.util.concurrent…...
【Java】PAT Basic Level 1023 组个最小数
题目 1024 组个最小数 作者 CAO, Peng 单位 Google 给定数字 0-9 各若干个。你可以以任意顺序排列这些数字,但必须全部使用。目标是使得最后得到的数尽可能小(注意 0 不能做首位)。例如:给定两个 0,两个 1ÿ…...
Redis中设置Hash数据类型的过期时间
1 方案 可以先对key进行赋值,然后对key设置一个过期时间。 (1)依赖 <dependency><groupId>redis.clients</groupId><artifactId>jedis</artifactId><version>2.7.3</version></dependency>…...
你真的了解CPU和GPU?
目录 先举个栗子 CPU 什么是CPU CPU的定义 CPU的组成 CPU的功能 GPU 什么是GPU GPU的定义 GPU的组成 GPU的功能 CPU和GPU的区别 先举个栗子 假设你正在编辑一份文档,这时可以将CPU和GPU的角色比喻为文档编辑过程中的两个不同任务。 1. CPU CPU就好比是…...
HarmonyOS开发:NodeJs脚本实现组件化动态切换
前言 上篇文章,我们使用NodeJs脚本完成了HarmonyOS项目的组件化运行,但是由于脚本是基于4.0.0.400版本的DevEco Studio开发的,可能在配置文件的修改上有些许差距,那么遇到这种情况怎么办,一种是再写一套针对性的脚本文…...
基于springboot实现就业信息管理系统项目【项目源码+论文说明】计算机毕业设计
基于springboot实现就业信息管理系统演示 摘要 随着信息化时代的到来,管理系统都趋向于智能化、系统化,就业信息管理系统也不例外,但目前国内仍都使用人工管理,市场规模越来越大,同时信息量也越来越庞大,人…...
Vue组件的本质和手写通过render渲染函数渲染组件
1.组件的本质 组件就是一组 DOM 元素的封装,本质就是一个对象 (mounted函数中打印一下组件即可看到打印的是一个对象) 如何利用javascript对象来描述一个组件? const MyComponent {render() {return {tag: div,props: {onClick: () > alert(hell…...
【优选算法系列】第一节.双指针(283. 移动零和1089. 复写零)
作者简介:大家好,我是未央; 博客首页:未央.303 系列专栏:优选算法系列 每日一句:人的一生,可以有所作为的时机只有一次,那就是现在!!!!…...
Vue(uniapp)父组件方法和子组件方法执行优先顺序
涉及到的知识点:watch监控:先看问题,父组件从后端通过$ajax获取数据,在将父组件将值传输给子组件,使用子组件使用created钩子函数获取数据,按自己的想法应该是父组件先获取后端数据,在传入给子组…...
怎么突破反爬虫机制
在当今的数字化时代,网络爬虫已经成为了收集信息和数据的重要工具。然而,许多网站和平台都配备了反爬虫机制,以防止恶意攻击和过度访问。对于普通用户来说,如何突破这些反爬虫机制呢?本文将为你提供一些实用的技巧和建…...
CSP-J2023入门组第二轮T4:旅游巴士
题目描述 小 Z 打算在国庆假期期间搭乘旅游巴士去一处他向往已久的景点旅游。 旅游景点的地图共有 n n n 处地点,在这些地点之间连有 m m m 条道路。其中 1 1...
OS的Alarm定时器调度机制
调度表触发的任务在编译时就被静态定义,任务的触发时间和执行顺序是固定的。这种方式适用于已知的、固定的任务触发模式,例如周期性任务或事件驱动任务。而使用 Alarm 机制触发的任务具有更大的灵活性。Alarm 允许在运行时动态地设置和修改任务的触发时间…...
I2C协议
1.简介 IIC(Inter-Integrated Circuit)其实是IICBus简称,所以中文应该叫集成电路总线,它是一种串行通信总线,使用多主从架构,半双工通信,由飞利浦公司在1980年代为了让主板、嵌入式系统或手机用…...
全栈经验总结(不间断更新)
1.当后端传回来的值为列表套字典[{"id":1,"num":"1"},{"id":2"num":"3"}],如果要在vue3里面渲染图片,可以这样操作 <el-form-item label"图片:"><el-uploa…...
什么是恶意代码?
前言:本文旨在分享交流技术,在这里对恶意代码进行全面的介绍和讲解 目录 一.什么是恶意代码 二.恶意代码的发展史 三.恶意代码的相关定义 四.恶意代码攻击机制 PE病毒 PE文件的格式 脚本病毒 脚本文件隐藏方法 宏病毒 浏览器恶意代码 U盘病毒 …...
【Linux】C语言执行shell指令
在C语言中执行Shell指令 在C语言中,有几种方法可以执行Shell指令: 1. 使用system()函数 这是最简单的方法,包含在stdlib.h头文件中: #include <stdlib.h>int main() {system("ls -l"); // 执行ls -l命令retu…...
Mac软件卸载指南,简单易懂!
刚和Adobe分手,它却总在Library里给你写"回忆录"?卸载的Final Cut Pro像电子幽灵般阴魂不散?总是会有残留文件,别慌!这份Mac软件卸载指南,将用最硬核的方式教你"数字分手术"࿰…...
使用 Streamlit 构建支持主流大模型与 Ollama 的轻量级统一平台
🎯 使用 Streamlit 构建支持主流大模型与 Ollama 的轻量级统一平台 📌 项目背景 随着大语言模型(LLM)的广泛应用,开发者常面临多个挑战: 各大模型(OpenAI、Claude、Gemini、Ollama)接口风格不统一;缺乏一个统一平台进行模型调用与测试;本地模型 Ollama 的集成与前…...
Golang——9、反射和文件操作
反射和文件操作 1、反射1.1、reflect.TypeOf()获取任意值的类型对象1.2、reflect.ValueOf()1.3、结构体反射 2、文件操作2.1、os.Open()打开文件2.2、方式一:使用Read()读取文件2.3、方式二:bufio读取文件2.4、方式三:os.ReadFile读取2.5、写…...
云安全与网络安全:核心区别与协同作用解析
在数字化转型的浪潮中,云安全与网络安全作为信息安全的两大支柱,常被混淆但本质不同。本文将从概念、责任分工、技术手段、威胁类型等维度深入解析两者的差异,并探讨它们的协同作用。 一、核心区别 定义与范围 网络安全:聚焦于保…...
2025年低延迟业务DDoS防护全攻略:高可用架构与实战方案
一、延迟敏感行业面临的DDoS攻击新挑战 2025年,金融交易、实时竞技游戏、工业物联网等低延迟业务成为DDoS攻击的首要目标。攻击呈现三大特征: AI驱动的自适应攻击:攻击流量模拟真实用户行为,差异率低至0.5%,传统规则引…...
JUC并发编程(二)Monitor/自旋/轻量级/锁膨胀/wait/notify/锁消除
目录 一 基础 1 概念 2 卖票问题 3 转账问题 二 锁机制与优化策略 0 Monitor 1 轻量级锁 2 锁膨胀 3 自旋 4 偏向锁 5 锁消除 6 wait /notify 7 sleep与wait的对比 8 join原理 一 基础 1 概念 临界区 一段代码块内如果存在对共享资源的多线程读写操作…...
SpringCloud优势
目录 完善的微服务支持 高可用性和容错性 灵活的配置管理 强大的服务网关 分布式追踪能力 丰富的社区生态 易于与其他技术栈集成 完善的微服务支持 Spring Cloud 提供了一整套工具和组件来支持微服务架构的开发,包括服务注册与发现、负载均衡、断路器、配置管理等功能…...
Spring AI中使用ChatMemory实现会话记忆功能
文章目录 1、需求2、ChatMemory中消息的存储位置3、实现步骤1、引入依赖2、配置Spring AI3、配置chatmemory4、java层传递conversaionId 4、验证5、完整代码6、参考文档 1、需求 我们知道大型语言模型 (LLM) 是无状态的,这就意味着他们不会保…...
RMQ 算法详解(区间最值问题)
RMQ 算法详解(区间最值问题) 问题介绍解决方法暴力法ST表法基本思想算法步骤C实现 问题介绍 RMQ问题是OI中经常遇到的问题,主要是一下形式: 给你一堆数,不断的对里面的数进行操作,例如:让某个…...
