飞书云文档:蓝桥杯web组知识点——ES6篇https://uestc.feishu.cn/docx/V9JrdJF4JoAJSYx7cUvcHhKOnuc?from=from_copylink建议打开飞书云文档食用,非飞书用户也可查看
目录:
预览图:
飞书云文档部分语法csdn并不支持,建议到飞书云文档查看
⛷️考点
🖱️新增关键字
-
var 关键字的缺点
变量提升机制的问题
还记得在 JavaScript 中我们学过定义变量的方式吗?😏
我们声明变量的唯一方式是使用 var
关键字,但其实使用 var
关键字定义变量会遇到一些麻烦,不知道同学们在开发代码时,是否遇到如下情景。
function getNumber(isNumber) { if (isNumber) { var num = "7"; } else { var notNum = "not number!"; console.log(num); } } getNumber(false);
我们在控制台可以看到以下报错:
很奇怪吧!我们明明在函数中定义了 num
变量,为什么会说没有定义呢?🤔
其实在 JavaScript 中有一个提升机制,就是无论你在哪里使用 var
关键字声明变量,它都会被提升到当前作用域的顶部。在运行 getNumber
函数时,实际上执行结构是下面这个样子。
function getNumber(isNumber) { var num; var notNum; if (isNumber) { num = "7"; } else { notNum = "not number!"; console.log(num); } } getNumber(false);
因为在开头定义变量时,没有给 num
变量赋任何值,并且 getNumber
传入的是 false
,导致 if
语句未执行,num
未被赋值,所以控制台输出 undefined。
变量重复声明的问题
我们知道使用 var
关键字声明的变量可以重复赋值,但在某些情况下会造成一些问题。例如下面的情景:
function Sum(arrList) { var sum = 0; for (var i = 0; i < arrList.length; i++) { var arr = arrList[i]; for (var i = 0; i < arr.length; i++) { sum += arr[i]; } } return sum; } var arr = [1, 2, 3, 4, 5]; document.write(Sum(arr));
如果在我们的环境中运行这段代码,环境会卡死。🥶
这是因为在两层 for
循环中我们使用同一变量 i
进行赋值时,代码在执行过程中,第二层的 for
循环会覆盖外层变量 i
的值。
非块作用域的问题
使用 var
关键字定义的变量只有两种作用域,全局作用域和函数作用域,两者均不是块结构,会造成变量声明的提升。这可能出现下面这种问题:
function func() { for (var i = 0; i < 5; i++) {} document.write(i); // 5 } func();
运行上述代码后,你会发现页面上会显示 5。我们虽然是在 for
循环中定义的 i
变量,但由于变量被提升到 for
语句之上,所以退出循环后,变量 i
并没有被销毁,我们能够在循环外获取它的值。
-
let 关键字
基于上述三个问题,下面给大家一一解答~ 👻
解决变量提升机制问题
ES6 为我们提供了 let 关键字,它解决了变量提升到作用域顶部的问题。因为它的作用域是块,而不是提升机制了。
新建一个 index.html
文件,在其中定义一个 getNumber
函数,并用 let
来定义变量,写入以下代码。
function getNumber(isNumber) { if (isNumber) { let num = "7"; } else { let notNum = "not number!"; console.log(num); } } getNumber(false);
注意:以后实验中只展示 JS 的代码,关于 HTML 结构不再展示。
报错信息如下:
ReferenceError 是一个引用类型的错误,num is not defined 意思是 num
变量并不存在。
这是为什么呢?🤔
我们刚刚说过 let
关键字声明变量,其作用域是一个块,如果我们是在花括号 {}
里面声明变量,那么变量会陷入暂时性死区,也就是在声明之前,变量不可以被使用。
在上面代码中,我们的 num
变量是放在 if(){}
这个块中,并没有在 else{}
块中,所以会形成暂时性死区。
解决变量重复声明的问题
虽然 let
关键字声明的变量可以重新赋值,但是它与 var
关键字有所不同,let
关键字不能在同一作用域内重新声明,而 var
可以。
新建一个 index1.html
文件,在文件中使用 let
关键字重复定义变量。
let i = 5; let i = 6; console.log(i);
可以看到控制台会报参数错误(SyntaxError)。
如果将上面代码中的 let
关键字改为 var
关键字便不会报错了。
var i = 5; var i = 6; console.log(i);
解决非块级作用域的问题
前面我们已经说过使用 var
关键字定义变量,只有两种作用域,函数作用域和全局作用域,这两种都是非块级作用域。而 let
关键字定义的变量是块级作用域,就避免了变量提升。我们来看个例子。
新建一个 index2.html
文件,在其中写入以下内容。
function func() { for (let i = 0; i < 5; i++) {} console.log(i); } func();
你会发现,控制台报错了。
这是因为上面代码中的 i
变量只存在于 for 循环这个块中,当循环结束,i
变量就被销毁了,所以在 for 循环外访问不到。
-
const 关键字
在 ES6 中,为我们提供了另一个关键字 const 用于声明一个只读的常量。且一旦声明,常量的值就不能改变。如果你尝试反复赋值的话,则会引发错误。例如:
const MaxAge = 100; MaxAge = 10; console.log(MaxAge);
既然是不可改变,那么我们在定义时,必须对它进行初始化,不然也会报错。例如:
const Num; console.log(Num);
对于 const
关键字定义的变量值,不可改变在于两个方面:
-
值类型
值类型是指变量直接存储的数据,例如:
const num = 20;
这里 num
变量就是值类型,我们使用的是 const
关键字来定义 num,故赋予变量 num
的值 20 是不可改变的。
-
引用类型
引用类型是指变量存储数据的引用,而数据是放在数据堆中,比如,用 const 声明一个数组。
const arr = ["一", "二", "三"];
如果你尝试去修改数组,同样会报错。
const arr = ["一", "二", "三"]; arr = ["五", "六", "七"];
但是,使用 const
关键字定义的引用类型还是可以通过数组下标去修改值 ⭐️。
例如:
const arr = ["一", "二", "三"]; arr[0] = "四"; arr[1] = "五"; arr[2] = "六"; console.log(arr);
在控制台会显示:
这是为什么呢?🤔
因为变量 arr
保存的是数组的引用,并不是数组中的值,只要引用的地址不发生改变就不会保错。这就相当于一个房子,它拥有固定的位置,但住在房子里的人不一定固定。
⛱️字符串占位符
在 ES5 中,如果要把变量和字符串放在一起输出,你可能会想到使用 +
号来拼接。
let a = 2; let b = 4; console.log("a = " + a + ", b = " + b + ", sum = " + (a + b));
这样拼接的过程是很容易出错的。
在模板字面量中,你可以把合法的 JavaScript 表达式嵌入到占位符中并将其作为字符串的一部分输出。
那什么是 JavaScript 中的占位符呢?🤔
在 JavaScript 中,占位符由 ${}
符号组成,在花括号的中间可以包含任意 JavaScript 表达式。我们来举个例子吧~
新建一个 index2.html
文件,在文件中写入以下内容。
let str = `LanQiao Courses`; let message = `I like ${str}.`; console.log(message);
在控制台可以看到如下效果:
在上面代码中,占位符 ${str}
会访问变量 str
的字符串,并将其值插入到 message
字符串中,变量 message
会一直保留着这个结果。
我们刚刚说里面可以包含任意 JavaScript 的表达式,那我们来验证一下,写入一个加法式子,看看能不能正确输出。代码如下所示:
let a = 2; let b = 1; let sum = `a+b=${a + b}`; console.log(sum);
在控制台可以看到如下效果:
😶🌫️字符串的新增方法
在 ES6 中增加了处理字符串的方法,这些新方法弥补了 ES5 语法的一些不足之处。
-
includes()
-
startsWith()
-
endsWith()
-
repeat()
-
replaceAll()
判断指定字符串是否存在
在 ES5 中,我们要判断某个字符串是否包含指定字符串时,可以用 indexOf()
方法来判断,该方法可以返回指定字符串在某个字符串中首次出现的位置,其实这样还是比较麻烦的。在 ES6 中,为我们新增了三种方法来判断字符串是否包含在其中。
-
includes():判断是否包含指定字符串,如果包含返回 true,反之 false。
-
startsWith():判断当前字符串是否以指定的子字符串开头,如果是则返回 true,反之 false。
-
endsWith():判断当前字符串是否以指定的子字符串结尾,如果是则返回 true,反之 false。
重复字符串
repeat(n) 方法用于返回一个重复 n
次原字符串的新字符串,其参数 n
为整数,如果设置 n
为小数,会自动转换为整数。
例子:
let str = "HELLO"; console.log(str.repeat(4));
在控制台会看到如下显示:
从上图可以看到输出了由 4 个 HELLO
组成的新字符串。
替换字符串
在 ES5 中有一个 replace()
方法可以替换指定字符串,不过它只能替换匹配到的第一个字符串,如果想匹配整个字符串中所有的指定字符串是很麻烦的。
在 ES6 中,为我们提供了 replaceAll() 方法来解决这个问题,它可以用来替换所有匹配的字符串。
其语法格式为:
string.replaceAll("待替换的字符", "替换后的新字符");
let str = "HELLOWHELLOWHELLO"; console.log(str.replaceAll("W", "_"));
在控制台可以看到如下效果:
可以看到原字符串中的所有 W
都用 _
代替了。
🪸创建数组
Array.of()
同学们是否发现在之前的学习中,我们用 Array 对象来创建数组,会出现一些奇奇怪怪的问题。比如下面这些情况:
let arr = new Array(5); console.log("数组长度:" + arr.length); console.log("arr[0]:" + arr[0]); console.log("arr[4]:" + arr[4]);
在控制台显示如下:
我们可以看到打印出数组的长度为 5,Array()
中的 5 没有作为数组的元素被输出,而是被当作了数组的长度。
假如 Array()
中不是一个正整数,而是一个字符串,看看会发生什么事呢~ 🤔
let arr = new Array("5"); console.log("数组长度:" + arr.length); console.log("arr[0]:" + arr[0]);
在控制台显示如下:
刚刚我们写入一个整数时,被看作是数组的长度,我们再来发挥一下,假如我们在 Array()
中写入两个整数看看会发生什么~ 😜
let arr = new Array(3, 4); console.log("数组长度:" + arr.length); console.log("arr[0]:" + arr[0]); console.log("arr[1]:" + arr[1]);
在控制台显示如下:
参数 3 和 4 被看成了数组中的数据。你在 Array()
中多写几个元素,可以看到它们都会被当成数组的元素。
那我们看看加入几个字符串呢?😏
let arr = new Array(4, "7", "8"); console.log("数组长度:" + arr.length); console.log("arr[0]:" + arr[0]); console.log("arr[1]:" + arr[1]); console.log("arr[2]:" + arr[2]);
在控制台显示如下:
可以看到整数和字符类型均被当作了数组的元素。
用上面这样的方式传入值是存在一定风险的。Array.of() 为我们解决了这个问题。我们来看看它是怎么用的。👻
Array.of()
的语法格式如下:
Array.of(element 0, element 1, ..., element N)
返回具有 N 个元素的数组。
Array.from()
在 ES6 之前,如果要把非数组类型的对象转换成一个数组,我们能想到最简单的办法是什么呢?🤔 是不是用 [].slice.call()
把一个非数组类型变为数组类型。举个例子:
let arrLike = { 0: "🍎", 1: "🍐", 2: "🍊", 3: "🍇", length: 4, }; var arr = [].slice.call(arrLike); console.log("arr:" + arr);
在控制台显示如下:
在 ES6 中为我们提供了 Array.from() 代替了这种旧办法。
Array.from()
方法可以将以下两类对象转为数组。
-
类似数组的对象(array-like-object)。
-
可遍历的对象(iterable-object)。
其基本使用格式为:
Array.from(待转换的对象);
例子:
let arrLike = { 0: "🍎", 1: "🍐", 2: "🍊", 3: "🍇", length: 4, }; var arr = Array.from(arrLike); console.log("arr:" + arr);
在控制台可以看到与上面一样的效果。
注意:Array.from() 方法是基于原来的对象创建的一个新数组。