ES6


ES6-ES11 学习笔记

学习笔记的来源:在B站观看尚硅谷的ES6视频教程并做相应的笔记,仅供参考

一、概述

1、什么是 ECMA

ECMA(European Computer Manufacturers Association)中文名称为欧洲计算机制造商协会,这个组织的目标是评估、开发和认可电信和计算机标准。1994 年后该组织改名为 Ecma 国际

2、什么是 ECMAScript

ECMAScript 是由 Ecma 国际通过 ECMA-262 标准化脚本 的程序设计语言;

百度百科:https://baike.baidu.com/history/ECMAScript/1889420/144946978

3、什么是 ECMA-262

Ecma 国际制定了许多标准,而 ECMA-262 只是其中的一个,所有标准列表查看:

http://www.ecma-international.org/publications/standards/Standard.htm

4、ECMA-262 历史

ECMA-262(ECMAScript)历史版本查看网址:
http://www.ecma-international.org/publications/standards/Ecma-262-arch.htm

注:从 ES6 开始,每年发布一个版本,版本号比年份最后一位大 1;

5、谁在维护 ECMA-262

TC39(Technical Committee 39)是推进 ECMAScript 发展的委员会。其会员都是公司(其中主要是浏览器厂商,有苹果、谷歌、微软、因特尔等)。TC39 定期召开会议,会议由会员公司的代表与特邀专家出席;

6、为什么要学习 ES6

  • ES6 的版本变动内容最多,具有里程碑意义;
  • ES6 加入许多新的语法特性,编程实现更简单、高效;
  • ES6 是前端发展趋势,就业必备技能;

7、ES6 兼容性

查看网址:http://kangax.github.io/compat-table/es6

二、ES6 新特性

0、功能概述

1、let 关键字
? 声明局部变量;

2、const 关键字
? 声明常量;
3、变量和对象的解构赋值
? 简化变量声明;
4、模板字符串
? 声明自带格式的字符串;
5、简化对象和函数写法
? 简化对象和函数写法;
6、箭头函数
? 简化函数写法;
7、ES6中函数参数的默认值
? 给函数的参数设置默认值;
8、rest参数
? 拿到实参;
9、扩展运算符
? 将一个数组转为用逗号分隔的参数序列;
10、Symbol
? 表示独一无二的值;
11、迭代器
? 用来遍历集合、数组等;
12、生成器
? 是一种异步编程解决方案;
13、Promise
? 非常强大的异步编程的新解决方案;
14、Set集合
? 类似数组,但元素不重复的集合;
15、Map集合
? 键值对集合;
16、class类
? 像java实体类一样声明js类;
17、数值扩展
? 增加一些数值相关的方法等;
18、对象扩展
? 增加一些对象相关的方法等;
19、模块化
? 模块化、组件化;
20、Babel对ES6模块化代码转换
? 为了适配浏览器,将更新的ES规范转换成ES5规范;
21、ES6模块化引入NPM包
? 像导入模块一样导入npm包;

1、let 关键字

特性:

let 关键字用来声明变量,使用 let 声明的变量有几个特点:

  1. 不允许重复声明
  2. 块儿级作用域(局部变量)
  3. 不存在变量提升
  4. 不影响作用域链

let创建变量代码示例:

// let关键字使用示例:
let a; // 单个声明
let b,c,d; // 批量声明
let e = 100; // 单个声明并赋值
let f = 521, g = 'iloveyou', h = []; // 批量声明并赋值
不允许重复声明:

代码实现:

// 1. 不允许重复声明;
let dog = "狗";
let dog = "狗";
// 报错:Uncaught SyntaxError: Identifier 'dog' has already been declared

运行结果:

块儿级作用域(局部变量):

代码实现:

// 2. 块儿级作用域(局部变量);
{
let cat = "猫";
console.log(cat);
}
console.log(cat);
// 报错:Uncaught ReferenceError: cat is not defined

运行结果:

不存在变量提升:

什么是变量提升
就是在变量创建之前使用(比如输出:输出的是默认值),let不存在,var存在;
代码实现:

// 3. 不存在变量提升;
// 什么是变量提升:就是在变量创建之前使用(比如输出:输出的是默认值),let不存在,var存在;
console.log(people1); // 可输出默认值
console.log(people2); // 报错:Uncaught ReferenceError: people2 is not defined
var people1 = "大哥"; // 存在变量提升
let people2 = "二哥"; // 不存在变量提升

运行结果:

不影响作用域链:

什么是作用域链:很简单,就是代码块内有代码块,跟常规编程语言一样,上级代码块中的局部变量下级可用

代码实现:

// 4. 不影响作用域链;
// 什么是作用域链:很简单,就是代码块内有代码块,跟常规编程语言一样,上级代码块中的局部变量下级可用
{
	let p = "大哥";
	function fn(){
		console.log(p); // 这里是可以使用的
	}
	fn();
}

运行结果:

全部演示代码:





    
    let



    let
    



应用场景:
以后声明变量使用 let 就对了;

let案例:点击div更改颜色

代码实现:





    
    
    let案例:点击div更改颜色
    
    



    

运行结果:

2、const 关键字

特性:

const 关键字用来声明常量,const 声明有以下特点:

  1. 声明必须赋初始值;
  2. 标识符一般为大写(习惯);
  3. 不允许重复声明;
  4. 值不允许修改;
  5. 块儿级作用域(局部变量);

const创建变量代码示例:





    
    const



    



声明必须赋初始值:

代码实现

// 1. 声明必须赋初始值;       
const CAT;

运行结果:

不允许重复声明:

代码实现:

// 3. 不允许重复声明;
const CAT = "喵喵";
const CAT = "喵喵";

运行结果:

值不允许修改:

注意:对数组元素的修改和对对象内部的修改是可以的(数组和对象存的是引用地址);
代码实现:

// 4. 值不允许修改;
const CAT = "喵喵";
CAT = "咪咪";

运行结果:

块儿级作用域(局部变量):

代码实现:

// 5. 块儿级作用域(局部变量);
{
const CAT = "喵喵";
console.log(CAT);
}
console.log(CAT);

运行结果:

全部演示代码:





    
    const



    



应用场景:
声明对象类型使用 const,非对象类型声明选择 let;

3、变量和对象的解构赋值

什么是解构赋值:
ES6 允许按照一定模式,从数组和对象中提取值,对变量进行赋值,这被称为解构赋值;

代码演示及相关说明:





    
    解构赋值



    



应用场景:
频繁使用对象方法、数组元素,就可以使用解构赋值形式;

4、模板字符串

概述
模板字符串(template string)是增强版的字符串,用反引号(`)标识,特点:

  • 字符串中可以出现换行符;
  • 可以使用 ${xxx} 形式引用变量;

代码演示及相关说明:





    
    



    


应用场景:
当遇到字符串与变量拼接的情况使用模板字符串

5、简化对象和函数写法

概述:
ES6 允许在大括号里面,直接写入变量和函数,作为对象的属性和方法。这样的书写更加简洁;

代码示例及相关说明:




    
    简化对象写法



    


6、箭头函数

概述
ES6允许使用箭头(=>)定义函数,箭头函数提供了一种更加简洁的函数书写方式,箭头函数多用于匿名函数的定义

箭头函数的注意点

  1. 如果形参只有一个,则小括号可以省略;
  2. 函数体如果只有一条语句,则花括号可以省略,函数的返回值为该条语句的执行结果;
  3. 箭头函数 this 指向声明时所在作用域下 this 的值
  4. 箭头函数不能作为构造函数实例化
  5. 不能使用 arguments;

特性

  1. 箭头函数的this是静态的,始终指向函数声明时所在作用域下的this的值;
  2. 不能作为构造函数实例化对象;
  3. 不能使用 arguments 变量;

代码演示及相关说明:
注意箭头函数不会更改 this 指向,用来指定回调函数会非常合适





    
    箭头函数



    



运行结果:

需求-1:点击 div 2s 后颜色变成『粉色』:

传统写法存在问题:
代码:





    
    箭头函数的实践和应用场景
    



    
    


传统写法问题解决:





    
    箭头函数的实践和应用场景
    



    
    



ES6写法:
(从这个案例中就能理解ES6箭头函数的特性了)





    
    箭头函数的实践和应用场景
    



    
    



需求-2 从数组中返回偶数的元素:





    
    箭头函数的实践和应用场景
    



    
    



7、ES6中函数参数的默认值

概述:

ES允许给函数的参数赋初始值;

代码示例及相关说明:





    
    函数参数默认值



    



8、rest参数

概述
ES6 引入 rest 参数,用于获取函数的实参,用来代替 arguments;
参考文章:https://www.jianshu.com/p/50bcb376a419

代码示例及相关说明:





    
    rest参数



    



运行结果:

9、扩展运算符

介绍:
... 扩展运算符能将数组转换为逗号分隔的参数序列;
扩展运算符(spread)也是三个点(...)。它好比 rest 参数的逆运算,将一个数组转为用逗号分隔的参
数序列,对数组进行解包;





    
    扩展运算符



    



运行结果:

应用





    
    扩展运算符应用



    

运行结果:

10、Symbol

Symbol 概述:

ES6 引入了一种新的原始数据类型 Symbol,表示独一无二的值。它是JavaScript 语言的第七种数据类型,是一种类似于字符串的数据类型
参考文章:https://blog.csdn.net/fesfsefgs/article/details/108354248

Symbol 特点:

  1. Symbol 的值是唯一的,用来解决命名冲突的问题;
  2. Symbol 值不能与其他数据进行运算;
  3. Symbol 定义的对象属性不能使用for…in循环遍历 ,但是可以使用Reflect.ownKeys 来获取对象的所有键名;

基本使用:





    

    
    symbol




    



Symbol创建对象属性:






    

    
    Symbol创建对象属性




    



Symbol内置值:

概述:
除了定义自己使用的 Symbol 值以外,ES6 还提供了 11 个内置的 Symbol 值,指向语言内部使用的方法。可以称这些方法为魔术方法,因为它们会在特定的场景下自动执行;

方法:

特别的: Symbol内置值的使用,都是作为某个对象类型的属性去使用

演示





    
    
    Symbol内置属性



    



运行结果:

11、迭代器

概述
遍历器(Iterator)就是一种机制。它是一种接口,为各种不同的数据结构提供统一的访问机制。任何数据结构只要部署 Iterator 接口,就可以完成遍历操作;

特性
ES6 创造了一种新的遍历命令 for...of 循环,Iterator 接口主要供 for...of 消费;

原生具备 iterator 接口的数据(可用 for of 遍历):

  • Array;
  • Arguments;
  • Set;
  • Map;
  • String;
  • TypedArray;
  • NodeList;

工作原理

  1. 创建一个指针对象,指向当前数据结构的起始位置;
  2. 第一次调用对象的 next 方法,指针自动指向数据结构的第一个成员;
  3. 接下来不断调用 next 方法,指针一直往后移动,直到指向最后一个成员;
  4. 每调用 next 方法返回一个包含 value 和 done 属性的对象;

注:需要自定义遍历数据的时候,要想到迭代器;

代码示例及相关说明:





    
    迭代器



    



运行结果:

迭代器自定义遍历对象:

代码实现:





    
    迭代器自定义遍历数据



    



运行结果:

12、生成器

概述
生成器函数是 ES6 提供的一种异步编程解决方案,语法行为与传统函完全不同;

异步编程----> (之前我们用的纯回调函数都是异步编程,例如 node fs ajax mongodb)

基本使用





    
    生成器



    



运行结果:

生成器函数的参数传递





    
    生成器函数的参数传递



    



运行结果:

生成器函数实例1:





    
    生成器函数实例1



    



运行结果:

生成器函数实例2:





    
    生成器函数实例2



    



运行结果:

13、Promise

概述:

Promise 是 ES6 引入的异步编程的新解决方案。语法上 Promise 是一个构造函数,用来封装异步操作并可以获取其成功或失败的结果;

Promise实现了以同步书写方式完成了异步回调功能

  1. Promise 构造函数: Promise (excutor) {};
  2. Promise.prototype.then 方法;
  3. Promise.prototype.catch 方法;

基本使用:





    
    Promise



    



如下图

Promise封装读取文件:

一般写法:

2-Promise封装读取文件.js:

//1. 引入 fs 模块(这是node的模块,如果还没学nodejs知识,可以先跳过)
const fs = require('fs');

//2. 调用方法读取文件
// fs.readFile('./resources/为学.md', (err, data)=>{
//     //如果失败, 则抛出错误
//     if(err) throw err;
//     //如果没有出错, 则输出内容
//     console.log(data.toString());
// });

//3. 使用 Promise 封装
const p = new Promise(function (resolve, reject) {
    //读取文件
    fs.readFile("./resources/为学.md", (err, data) => {
        //判断如果失败
        if (err) reject(err);
        //如果成功
        resolve(data);
    });
});

p.then(function (value) {
    console.log(value.toString());
}, function (reason) {
    console.log("读取失败!!");
});

resources/为学.md文件:

   为学
天下事有难易乎?
为之,则难者亦易矣;
不为,则易者亦难矣

执行:

node 2-Promise封装读取文件.js

执行结果:

Promise封装Ajax请求:

原生请求:





    
    
    发送 AJAX 请求



    



Promise.prototype.then:

代码实现及相关说明:

1、如果回调函数中返回的结果是 非promise 类型的数据

运行结果:

2、如果回调函数返回的是promise类型的数据

? 2.1、回调函数----》返回的Promise对象中----》调用reject方法

    

运行结果

?

2.2、回调函数----》返回的Promise对象中----》调用resovled方法

    

运行结果:

3、抛出错误的情况,返回的Promise对象中----》[[PromiseState]]: "rejected" ----》[[PromiseResult]]---》异常抛出的值

    

运行结果:

Promise链式调用
// 链式调用
// then里面两个函数参数,可以只写一个
p.then(value => { }, reason => { }).then(value => { }, reason => { });
console.log(result);
Promise对象catch方法:





    
    
    catch方法



    



运行结果

14、Set集合

概述:

ES6 提供了新的数据结构 Set(集合)。它类似于数组,但成员的值都是唯一的,集合实现了 iterator接口,所以可以使用『扩展运算符』和『for…of…』进行遍历,集合的属性和方法:

  1. size 返回集合的元素个数;
  2. add 增加一个新元素,返回当前集合;
  3. delete 删除元素,返回 boolean 值;
  4. has 检测集合中是否包含某个元素,返回 boolean 值;
  5. clear 清空集合,返回 undefined;

基本使用:

代码实现:





    
    Set集合



    



运行结果:

Set集合实践:





    
    
    Set 实践



    



15、Map集合

概述:

ES6 提供了 Map 数据结构。它类似于对象,也是键值对的集合。但是“键”的范围不限于字符串,各种类型的值(包括对象)都可以当作键。Map 也实现了iterator 接口,所以可以使用『扩展运算符』和『for…of…』进行遍历

Map 的属性和方法:

  1. size 返回 Map 的元素个数;
  2. set 增加一个新元素,返回当前 Map;
  3. get 返回键名对象的键值;
  4. has 检测 Map 中是否包含某个元素,返回 boolean 值;
  5. clear 清空集合,返回 undefined;

简单使用:

代码实现:





    
    Map集合



    



运行结果:

16、class类

概述:

ES6 提供了更接近传统语言的写法,引入了 Class(类)这个概念,作为对象的模板。通过 class 关键字,可以定义类。基本上,ES6 的 class 可以看作只是一个语法糖,它的绝大部分功能,ES5 都可以做到,新的 class 写法只是让对象原型的写法更加清晰、更像面向对象编程的语法而已;

知识点:

  1. class 声明类;
  2. constructor 定义构造函数初始化;
  3. extends 继承父类;
  4. super 调用父级构造方法;
  5. static 定义静态方法和属性;
  6. 父类方法可以重写;

class初体验:

代码实现:





    
    
    类声明



    



运行结果:

class静态成员:

注意:静态属性,属于类的属性,不属于实例对象的属性,所以可以用 类.xxx访问静态属性,不能用实例对象.xxx访问静态属性

代码实现:





    
    
    静态成员



    



ES5构造函数实现继承:

代码实现:





    
    
    对象继承



    



运行结果:

ES6class类继承:

代码实现:





    
    
    类继承-2



    



运行结果:

17、数值扩展

Number.EPSILON:Number.EPSILON 是 JavaScript 表示的最小精度;
EPSILON 属性的值接近于 2.2204460492503130808472633361816E-16;如果俩个数相减的绝对值小于Number.EPSILON,则认为这俩个数是相等的

二进制和八进制
ES6 提供了二进制和八进制数值的新的写法,分别用前缀 0b 和 0o 表示;

Number.isFinite() 与 Number.isNaN()
Number.isFinite() 用来检查一个数值是否为有限的;
Number.isNaN() 用来检查一个值是否为 NaN;

Number.parseInt() 与 Number.parseFloat()
ES6 将全局方法 parseInt 和 parseFloat,移植到 Number 对象上面,使用不变;

Math.trunc
用于去除一个数的小数部分,返回整数部分;

Number.isInteger:
Number.isInteger() 用来判断一个数值是否为整数;

代码实现和相关说明:
代码实现:





    
    
    数值扩展



    



18、对象扩展

概述:

ES6 新增了一些 Object 对象的方法:

  1. Object.is 比较两个值是否严格相等,与『===』行为基本一致(+0 与 NaN);
  2. Object.assign 对象的合并,将源对象的所有可枚举属性,复制到目标对象;
  3. proto、setPrototypeOf、 setPrototypeOf 可以直接设置对象的原型;

代码实现及相关说明:

代码实现:





    
    对象扩展



    



19、模块化

概述:

模块化是指将一个大的程序文件,拆分成许多小的文件,然后将小文件组合起来;

模块化的好处:

模块化的优势有以下几点:

  1. 防止命名冲突;
  2. 代码复用;
  3. 高维护性;

模块化规范产品:

ES6 之前的模块化规范有:

  1. CommonJS(只是一种规范) =>(规范的实现) NodeJS、Browserify;
  2. AMD(只是一种规范) =>(规范的实现) requireJS;
  3. CMD(只是一种规范) => (规范的实现) seaJS;

ES6 模块化语法:

模块功能主要由两个命令构成:export 和 import;
export 命令用于规定模块的对外接口(导出模块);
import 命令用于输入其他模块提供的功能(导入模块);

ES6暴露数据方式:

逐个导出模块:

m.js文件

// 分别暴露(导出)
export let school = "尚硅谷";
export function teach(){
	console.log("我们可以教你开发技术!");
}
统一导出模块:

n.js文件

// 统一暴露(导出)
let school = "尚硅谷";
function findJob(){
	console.log("我们可以帮你找到好工作!");
}
export {school,findJob}
默认导出模块

o.js文件

// 默认暴露(导出)
export default{
school : "尚硅谷",
change : function(){
console.log("我们可以帮你改变人生!");
}
}

模块化.html(引入和使用模块)





    
    模块化



    



运行结果:

ES6导入模块语法汇总:

模块化.html:





    
    
    ES6 模块化



    




使用模块化的另一种方式:

将js语法整合到一个文件app.js:

// 通用方式
// 引入m.js模块内容
import * as m from "./m.js";
console.log(m);
console.log(m.school);
m.teach();

使用模块化的另一种方式.html:



	
		
		使用模块化的另一种方式
	
	
		
	

运行结果:

20、Babel对ES6模块化代码转换

Babel概述:

Babel 是一个 JavaScript 编译器
Babel 能够将新的ES规范语法转换成ES5的语法
因为不是所有的浏览器都支持最新的ES规范,所以,一般项目中都需要使用Babel进行转换;

步骤:

使用Babel转换JS代码——打包成一个文件——使用时引入即可;

第一步:安装工具babel-cli(命令行工具) babel-preset-env(ES转换工具) browserify(打包工具,项目中使用的是webpack);

npm i babel-cli babel-preset-env browserify -D

第二步:初始化项目

npm init -y

第三步:使用babel转换

npx babel js目录 -d 转化后的js目录 --presets=babel-preset-env

例:

npx babel src/js -d dist/js --presets=babel-preset-env

第四步:打包

npx browserify 需要打包的js文件,一般是入口文件且已经被第三步babel编译过的文件 -o 打包后的文件路径

例:dist目录下的app.js是编译过后的文件

npx browserify dist/js/app.js -o dist/bundle.js

第五步:在使用时引入打包好的js文件:bundle.js


转换前后对比:
转换前:

//分别暴露
export let school = '尚硅谷';
export function teach() {
  console.log("我们可以教给你开发技能");
}

转换后:

"use strict";
Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.teach = teach;
//分别暴露
var school = exports.school = '尚硅谷';
function teach() {
  console.log("我们可以教给你开发技能");
}

21、ES6模块化引入NPM包

演示:
第一步:安装jquery:

npm i jquery

第二步:在app.js使用jquery

//入口文件
//修改背景颜色为粉色
import $ from 'jquery';// 相当于const $ = require("jquery");
$('body').css('background','pink');

三、ES7 新特性

功能概述

1、Array.prototype.includes

判断数组中是否包含某元素,语法:arr.includes(元素值);

2、指数操作符

幂运算的简化写法,例如:2的10次方:2**10;

1、Array.prototype.includes

概述:
Includes 方法用来检测数组中是否包含某个元素,返回布尔类型值;
判断数组中是否包含某元素,语法:arr.includes(元素值);





    
    includes



    


运行结果

2、指数操作符

概述:
在 ES7 中引入指数运算符 **,用来实现幂运算,功能与 Math.pow 结果相同;
幂运算的简化写法,例如:2的10次方:2**10;

代码实现:





    
    指数操作符



    



运行结果

四、ES8 新特性

功能概述

1、async 和 await
简化异步函数的写法;

2、对象方法扩展
对象方法扩展;

1、async 和 await

概述:
async 和 await 两种语法结合可以让异步代码看起来像同步代码一样;
简化异步函数的写法;

async 函数:

概述:

  1. async 函数的返回值为 promise 对象;
  2. promise 对象的结果由 async 函数执行的返回值决定;

代码实现:

情况1:返回的结果不是一个 Promise 类型的对象, 返回的结果就是成功 Promise 对象





    
    
    async函数



    



运行结果:

情况2:抛出错误, 返回的结果是一个失败的 Promise





    
    
    async函数



    



运行结果:

情况3:返回的结果如果是一个 Promise 对象,如果这个Promise对象中执行了resolve方法,则返回成功的Promise对象;反之亦然





    
    
    async函数



    



运行结果

await 表达式:

概述:

  1. await 必须写在 async 函数中;
  2. await 右侧的表达式一般为 promise 对象;
  3. await 返回的是 promise 成功的值;
  4. await 的 promise 失败了, 就会抛出异常, 需要通过 try...catch 捕获处理;

代码实现:

返回成功的案例:





    
    
    await



    



运行结果:

返回失败的案例:





    
    
    await



    



运行结果:

async 和 await 读取文件案例:

代码实现:

//1. 引入 fs 模块
const fs = require("fs");

//读取『为学』
function readWeiXue() {
    return new Promise((resolve, reject) => {
        fs.readFile("./resources/为学.md", (err, data) => {
            //如果失败
            if (err) reject(err);
            //如果成功
            resolve(data);
        })
    })
}

function readChaYangShi() {
    return new Promise((resolve, reject) => {
        fs.readFile("./resources/插秧诗.md", (err, data) => {
            //如果失败
            if (err) reject(err);
            //如果成功
            resolve(data);
        })
    })
}

function readGuanShu() {
    return new Promise((resolve, reject) => {
        fs.readFile("./resources/观书有感.md", (err, data) => {
            //如果失败
            if (err) reject(err);
            //如果成功
            resolve(data);
        })
    })
}

//声明一个 async 函数
async function main() {
    try {
        //获取为学内容
        let weixue = await readWeiXue();
        //获取插秧诗内容
        let chayang = await readChaYangShi();
        // 获取观书有感
        let guanshu = await readGuanShu();
        console.log(weixue.toString());
        console.log(chayang.toString());
        console.log(guanshu.toString());
    } catch (error) {
        console.log(error);
    }
}

main();

运行结果:

async 和 await 结合发送ajax请求:

代码实现:





    
    
    发送 AJAX 请求



    



运行结果:

2、对象方法扩展

Object.values、Object.entries和Object.getOwnPropertyDescriptors:

  1. Object.values()方法:返回一个给定对象的所有可枚举属性值的数组
  2. Object.entries()方法:返回一个给定对象自身可遍历属性 [key,value] 的数组(也可以这样理解:将对象转为二维数组);
  3. Object.getOwnPropertyDescriptors()该方法:返回指定对象所有自身属性的描述对象;

代码实现:





    
    
    ES8 对象方法扩展



    



运行结果:

对Object.getOwnPropertyDescriptors(对象名)的理解:

五、ES9 新特性

功能概述

1、Rest 参数与 spread 扩展运算符

? 在对象中使Rest参数与spread扩展运算符;

2、正则扩展
简化和增强正则匹配;

1、Rest 参数与 spread 扩展运算符

概述:

Rest 参数与 spread 扩展运算符在 ES6 中已经引入,不过 ES6 中只针对于数组,在 ES9 中为对象提供了像数组一样的 rest 参数和扩展运算符;

代码实现:





    
    
    对象展开



    
    




运行结果:

2、正则扩展:命名捕获分组

概述
ES9 允许命名捕获组使用符号『?』,这样获取捕获结果可读性更强;

代码实现:





    
    
    正则扩展-命名捕获分组



    



运行结果:

3、正则扩展:反向断言

概述:
ES9 支持反向断言,通过对匹配结果前面的内容进行判断,对匹配进行筛选;

代码实现:




    
    
    正则扩展-反向断言


    


运行结果:

4、正则扩展:dotAll 模式

概述:
正则表达式中点.匹配除回车外的任何单字符,标记/s改变这种行为,包括换行符(\n);

代码实现:

情况1:没有 模式修正符的情况:





    
    
    正则扩展-dotAll模式



    



运行结果:

虽然结果能出来,但是不建议这样匹配,如果字符串比较复杂,那么正则表达式就比较复杂且臃肿

例如字符串多加了span元素,那么正则表示式也要做相应的处理:

 let str = `
        `;
var reg = /
  • \s+.*?<\/span>\s+(.*?)<\/a>\s+

    (.*?)<\/p>/;

  • 由此可见,没有模式修正符的情况下,是不理想的

    情况2:模式修正符的情况:

    
    
    
    
        
        
        正则扩展-dotAll模式
    
    
    
        
    
    
    
    

    运行结果:

    正则表达式的解释:

    六、ES10 新特性

    功能概述

    1、Object.fromEntries:将二维数组或者map转换成对象;

    2、trimStart 和 trimEnd: 去除字符串前后的空白字符;

    3、Array.prototype.flat 与 flatMap : 将多维数组降维;

    4、Symbol.prototype.description: 获取Symbol的字符串描述;

    1、Object.fromEntries

    概述:

    将二维数组或者map转换成对象;
    之前学的Object.entries是将对象转换成二维数组;

    代码实现:

    
    
    
    
        
        
        Object.fromEntries
    
    
    
        
    
    
    
    

    运行结果:

    2、trimStart 和 trimEnd

    概述:
    去掉字符串前后的空白字符;

    代码实现:

    
    
    
        
        
        trimStart 与 trimEnd
    
    
        
    
    
    

    运行结果:

    3、Array.prototype.flat 与 flatMap

    概述:
    将多维数组转换成低维数组;

    代码实现:

    
    
    
    
        
        
        flat 与 flatMap
    
    
    
        
    
    
    
    

    运行结果:

    4、Symbol.prototype.description

    概述:
    获取Symbol的描述字符串;

    代码实现:

    
    
    
    
        
        
        Symbol.prototype.description
    
    
    
        
    
    
    
    

    七、ES11 新特性

    功能概述

    1、String.prototype.matchAll:用来得到正则批量匹配的结果;

    2、类的私有属性:私有属性外部不可访问直接;

    3、Promise.allSettled:获取多个promise执行的结果集;

    4、可选链操作符:简化对象存在的判断逻辑;

    5、动态 import 导入:动态导入模块,什么时候使用什么时候导入;

    6、BigInt:大整型;

    7、globalThis 对象:始终指向全局对象window;

    1、String.prototype.matchAll

    概述:
    用来得到正则批量匹配的结果;

    代码实现:

    
    
    
    
        
        
        String.prototype.matchAll
    
    
    
        
    
    
    
    

    运行结果:

    2、类的私有属性

    概述:
    私有属性外部不可访问直接;

    代码实现:

    
    
    
    
        
        
        私有属性
    
    
    
        
    
    
    
    

    3、Promise.allSettled

    概述:
    获取多个promise执行的结果集;
    代码实现:

    情况1: 参数都是返回成功状态

    
    
    
    
        
        
        Promise.allSettled
    
    
    
        
    
    
    
    

    运行结果:

    情况2: 有参数返回失败状态

    
    
    
    
        
        
        Promise.allSettled
    
    
    
        
    
    
    
    

    运行结果:

    情况3: 和Promise.all()方法的对比

    ? 情况3-1:若参数对象都返回成功的状态,能正确执行并能得到参数对象中resolved的值

    
    
    
    
        
        
        Promise.allSettled
    
    
    
        
    
    
    
    

    运行结果:

    情况3-2:若参数对象有返回失败状态,则all方法的返回结果就是失败的值

    
    
    
    
        
        
        Promise.allSettled
    
    
    
        
    
    
    
    

    运行结果:

    4、可选链操作符

    概述:
    如果存在则往下走,省略对对象是否传入的层层判断;

    代码实现:

    
    
    
        
        
        可选链操作符
    
    
        
    
    
    

    5、动态 import 导入

    概述:
    动态导入模块,需要用的时候才导入;

    代码实现:

    hello.js:

    export function hello(){
      alert('Hello');
    }
    

    app.js:

    // import * as m1 from "./hello.js"; // 传统静态导入
    //获取元素
    const btn = document.getElementById('btn');
    btn.onclick = function(){
      //import方法,动态导入
      import('./hello.js').then(module => {
        module.hello();
     });
    }
    

    动态import加载.html:

    
    
    
    
        
        
        动态 import 
    
    
    
        
        
    
    
    
    

    运行结果:

    6、BigInt

    概述:
    更大的整数;

    代码实现:

    
    
    
    
        
        
        BigInt
    
    
    
        
    
    
    
    

    7、globalThis 对象

    概述:
    始终指向全局对象window;

    代码实现:

    
    
    
    
        
        
        globalThis
    
    
    
        
    
    
    
    

    运行结果: