ES6-11这一篇就够啦
- ECMAScript 6-11
- 1、ECMAScript 相关介绍
- 1.1 ECMAScript简介
- 1.2 ES6的重要性
- 2、ECMAScript 6新特性
- 2.1 let关键字
- 2.2 const关键字
- 2.3 变量的解构赋值
- 2.4 模板字符串
- 2.5 简化对象写法
- 2.6 箭头函数
- 2.7 rest参数
- 2.8 spread扩展运算符
- 2.9 Symbol
- 2.10 迭代器
- 2.11 生成器
- 2.12 Promise
- 2.13 set
- 2.14 map
- 2.15 class类
- 2.16 数值扩展
- 2.17 对象扩展
- 2.18 模块化
- 3、ECMAScript 7新特性
- 3.1 Array.prototype.includes
- 3.2 指数操作符
- 4、ECMAScript 8新特性
- 4.1 async和await
- 4.2 对象方法的扩展
- 5、ECMAScript 9新特性
- 5.1 Rest/Spread属性
- 5.2.正则表达式命名捕获组
- 5.3.正则表达式反向断言
- 5.4.正则表达式dotAll模式
- 6、ECMAScript 10新特性
- 6.1 Object.fromEntries
- 6.2 trimStart 和 trimEnd
- 6.3 Array.prototype.flat 与flatMap
- 6.4 Symbol.prototype.description
- 7、ECMAScript 11新特性
- 7.1 类的私有属性
- 7.2 Promise.allSettled
- 7.3 String.prototype.matchAll
- 7.4 可选链操作符
- 7.5 动态import 导入
- 7.6 BigInt
- 7.7 globalThis对象
ECMAScript 6-11
1、ECMAScript 相关介绍
1.1 ECMAScript简介
- ECMA(European Computer Manufacturers Association)中文名称为欧洲计算机制造商协会,这个组织的目标是评估、开发和认可电信和计算机标准。1994 年后该组织改名为 ECMA 国际
- ECMAScript 是由 Ecma 国际通过 ECMA-262 标准化的脚本程序设计语言
- Ecma 国际制定了许多标准,而 ECMA-262 只是其中的一个,所有标准列表查看:http://www.ecma-international.org/publications/standards/Standard.html
- ECMA-262(ECMAScript)历史版本查看网址: http://www.ecma-international.org/publications/standards/Ecma-262-arch.htm
1.2 ES6的重要性
-
ES6 的版本变动内容最多,具有里程碑意义
-
ES6 加入许多新的语法特性,编程实现更简单、高效
-
ES6 是前端发展趋势,就业必备技能
-
http://kangax.github.io/compat-table/es6/ 可查看兼容性
2、ECMAScript 6新特性
2.1 let关键字
-
let关键字用来声明变量,使用let声明的变量有几个特点:
-
不允许重复声明
-
块级作用域
-
不存在变量提升
-
不影响作用域链
-
-
代码:
//声明变量
let a;
let b, c, d;
let e = 100;
let f = 521, g = 'iloveyou', h = [];
//1. 变量不能重复声明
// let star = '罗志祥';
// let star = '小猪';报错
//2. 块儿级作用域 全局, 函数, eval
// if else while for
// {
// let girl = '周扬青';
// }
// console.log(girl);//报错
//3. 不存在变量提升
// console.log(song);
// let song = '恋爱达人';//报错
//4. 不影响作用域链
let school = '河工大';
function fn() {
console.log(school);
}
fn();
}
- 应用场景:以后声明变量直接使用let
2.2 const关键字
-
const关键字用来声明常量,const声明有以下特点:
-
声明必须赋初始值
-
标识符一般为大写
-
不允许重复声明
-
值不允许修改
-
块级作用域
-
-
代码:
//声明常量
const SCHOOL = '河工大';
//1. 一定要赋初始值
// const A;//报错
//2. 一般常量使用大写(潜规则)
// const a = 100;
//3. 常量的值不能修改
// SCHOOL = 'HAUT';//报错
//4. 块儿级作用域
// {
// const PLAYER = 'UZI';
// }
// console.log(PLAYER);
//5. 对于数组和对象的元素修改, 不算做对常量的修改, 不会报错
//const TEAM = ['UZI','MXLG','Ming','Letme'];
// TEAM.push('Meiko');
- 注意:对象属性修改和数组元素变化不会出现const错误
- 应用场景:声明对象类型使用const,非对象类型声明选择let
2.3 变量的解构赋值
- ES6允许按照一定模式,从数组和对象中提取值,对变量进行赋值,这被称为解构赋值
- 代码:
//1. 数组的结构
// const F4 = ['小沈阳', '刘能', '赵四', '宋小宝'];
// let [xiao, liu, zhao, song] = F4;//解构赋值
// console.log(xiao);
// console.log(liu);
// console.log(zhao);
// console.log(song);
//2. 对象的解构
const zhao = {
name: '赵本山',
age: '不详',
xiaopin: function(){
console.log("我可以演小品");
}
};
let {name, age, xiaopin} = zhao;//解构赋值
console.log(name);
console.log(age);
console.log(xiaopin);
xiaopin();
let { xiaopin } = zhao;
xiaopin();
- 注意:频繁使用对象方法、数组元素,就可以使用解构赋值形式
2.4 模板字符串
-
模板字符串(template string)是增强版的字符串,用反引号(``)标识,
-
特点:
- 字符串中可以出现换行符
- 可以使用${xxx}形式输出变量
-
代码:
//1. 声明
let str = `我也是一个字符串哦!`;
console.log(str, typeof str);
//2. 内容中可以直接出现换行符
let str = `<ul>
<li>沈腾</li>
<li>玛丽</li>
<li>魏翔</li>
<li>艾伦</li>
</ul>`;
//3. 变量拼接
let lovest = '魏翔';
let out = `${lovest}是我心目中最搞笑的演员!!`;
console.log(out);
- 注意:当遇到字符串与变量拼接的情况使用模板字符串
2.5 简化对象写法
- ES6允许在大括号里面,直接写入变量和函数,作为对象的属性和方法。这样的书写更加简洁
- 代码:
let name = '尚硅谷';
let change = function(){
console.log('我们可以改变你!!');
}
const school = {
name,
change,
improve(){
console.log("我们可以提高你的技能");
}
}
console.log(school);
- 注意:对象简写形式简化了代码,所以以后用简写就对了
2.6 箭头函数
-
ES6允许使用「箭头」(=>)定义函数
-
箭头函数的注意点:
- 如果形参只有一个,则小括号可以省略
- 函数体如果只有一条语句,则花括号可以省略,函数的返回值为该条语句的执行结果
- 箭头函数this 指向声明时所在作用域下this 的值
- 箭头函数不能作为构造函数实例化
- 不能使用arguments
-
代码:
//普通函数
let fn = function(){
}
//箭头函数
let fn = (a,b) => {
return a + b;
}
//1. this 是静态的. this 始终指向函数声明时所在作用域下的 this 的值
function getName() {
console.log(this.name);
}
let getName2 = () => {
console.log(this.name);
}
//设置 window 对象的 name 属性
window.name = '河工大';
const school = {
name: "haut"
}
//直接调用
getName();//河工大
getName2();//河工大
//call 方法调用
getName.call(school);//haut
getName2.call(school);//河工大
//2. 不能作为构造实例化对象
// let Person = (name, age) => {
// this.name = name;
// this.age = age;
// }
// let me = new Person('xiao',30);
// console.log(me);
//3. 不能使用 arguments 变量
// let fn = () => {
// console.log(arguments);
// }
// fn(1,2,3);
//4. 箭头函数的简写
//1) 省略小括号, 当形参有且只有一个的时候
let add = n => {
return n + n;
}
console.log(add(9));
//2) 省略花括号, 当代码体只有一条语句的时候, 此时 return 必须省略
// 而且语句的执行结果就是函数的返回值
let pow = n => n * n;
console.log(pow(8));
- 注意:箭头函数不会更改this指向,用来指定回调函数会非常合适
2.7 rest参数
- ES6引入rest参数,用于获取函数的实参,用来代替arguments
- 代码:
// ES5 获取实参的方式
function date() {
console.log(arguments);
}
date('白芷', '阿娇', '思慧');//Array(3)
// rest 参数
function date(...args) {
console.log(args);// filter some every map
}
date('阿娇', '柏芝', '思慧');//Array(3)
// rest 参数必须要放到参数最后
function fn(a, b, ...args) {
console.log(a);
console.log(b);
console.log(args);
}
fn(1, 2, 3, 4, 5, 6);//1,2,Array(4)
- 注意: rest参数非常适合不定个数参数函数的场景
补充:参数默认值
- 代码:
//1. 形参初始值 具有默认值的参数, 一般位置要靠后(潜规则)
function add(a, b, c = 10) {
return a + b + c;
}
let result = add(1, 2);
console.log(result);
//2. 与解构赋值结合
function connect({ host = "127.0.0.1", username, password, port }) {
console.log(host)
console.log(username)
console.log(password)
console.log(port)
}
connect({
host: 'ASHIYI.com',
username: 'root',
password: 'root',
port: 3306
})
2.8 spread扩展运算符
- 扩展运算符(spread)也是三个点(…)。它好比 rest参数的逆运算,将一个数组转为用逗号分隔的参数序列,对数组进行解包
- 代码:
const tfboys = ['易烊千玺','王源','王俊凯'];
function chunwan(){
console.log(arguments);
}
chunwan(...tfboys);// chunwan('易烊千玺','王源','王俊凯')
//扩展运算符的应用
//1. 数组的合并
const kuaizi = ['王太利', '肖央'];
const fenghuang = ['曾毅', '玲花'];
// const zuixuanxiaopingguo = kuaizi.concat(fenghuang);
const zuixuanxiaopingguo = [...kuaizi, ...fenghuang];
console.log(zuixuanxiaopingguo);
//2. 数组的克隆
const sanzhihua = ['E', 'G', 'M'];
const sanyecao = [...sanzhihua];// ['E','G','M']
console.log(sanyecao);
//3. 将伪数组转为真正的数组
const divs = document.querySelectorAll('div');
const divArr = [...divs];
console.log(divArr);// arguments
2.9 Symbol
Symbol基本使用
-
ES6引入了一种新的原始数据类型 Symbol,表示独一无二的值。它是JavaScript语言的第七种数据类型,是一种类似于字符串的数据类型
-
Symbol特点
- Symbol的值是唯一的,用来解决命名冲突的问题
- Symbol值不能与其他数据进行运算
- Symbol定义的对象属性不能使用for …in循环遍历,但是可以使用Reflect.ownKeys来获取对象的所有键名
-
代码:
//创建Symbol
let s = Symbol();
// console.log(s, typeof s);
let s2 = Symbol('尚硅谷');
let s3 = Symbol('尚硅谷');
console.log(s2 === s3)//false
//Symbol.for 创建
let s4 = Symbol.for('尚硅谷');
let s5 = Symbol.for('尚硅谷');
console.log(s4 === s5)//true
//Symbol.for()不会每次调用就返回一个新的Symbol类型的值,而是先检查给定的参数字符串是否已存在,如果不存在才会新建一个并返回一个该字符串为名称的Symbol值
- 注:遇到唯一性的场景时要想到symbol
Symbol内置值
- 除了定义自己使用的Symbol值以外,ES6还提供了11个内置的Symbol值,指向语言内部使用的方法。可以称这些方法为魔术方法,因为它们会在特定的场景下自动执行
名称 | 功能 |
---|---|
Symbol.hasInstance | 当其他对象使用instanceof运算符,判断是否为该对象的实例时,会调用这个方法 |
Symbol.isConcatSpreadable | 对象的Symbol.isConcatSpreadable属性等于的是一个布尔值,表示该对象用于Array.prototype.concat()时,是否可以展开 |
Symbol.species | 创建衍生对象时,会使用该属性 |
Symbol.match | 当执行str.match(myObject)时,如果该属性存在,会调用它,返回该方法的返回值 |
symbol.replace | 当该对象被str.replace(myObject)方法调用时,会返回该方法的返回值 |
symbol.search | 当该对象被str.search (myObject)方法调用时,会返回该方法的返回值 |
Symbol.split | 当该对象被str.split (myObject)方法调用时,会返回该方法的返回值 |
Symbol.iterator | 对象进行for…of 循环时,会调用Symbol.iterator方法,返回该对象的默认遍历器 |
symbol.toPrimitive | 该对象被转为原始类型的值时,会调用这个方法,返回该对象对应的原始类型值 |
Symbol.toStringTag | 在该对象上面调用toString方法时,返回该方法的返回值 |
symbol. unscopables | 该对象指定了使用with关键字时,哪些属性会被with环境排除 |
2.10 迭代器
-
遍历器(lterator)就是一种机制。它是一种接口,为各种不同的数据结构提供统一的访问机制。任何数据结构只要部署lterator接口,就可以完成遍历操作
-
ES6创造了一种新的遍历命令for…of循环,lterator接口主要供 for…of消费
-
原生具备iterator接口的数据(可用for of 遍历)
a)Arrayb)Arguments
c)Set
d)Map
e)string
f)TypedArray
g)NodeList
-
工作原理
a)创建一个指针对象,指向当前数据结构的起始位置b)第一次调用对象的next方法,指针自动指向数据结构的第一个成员
c)接下来不断调用next方法,指针一直往后移动,直到指向最后一个成员
d)每调用next方法返回一个包含value(值)和 done(判断循环是否完成)属性的对象
-
-
代码:
//声明一个数组
const xiyou = ['唐僧', '孙悟空', '猪八戒', '沙僧'];
//使用 for...of 遍历数组
for (let v of xiyou) {
console.log(v);
}
- 注:需要自定义遍历数据的时候,要想到迭代器
2.11 生成器
- 生成器函数是ES6提供的一种异步编程解决方案,语法行为与传统函数完全不同
- 代码:
function * gen(){
yield '一只没有耳朵';
yield '一只没有尾部';
yield '真奇怪';
}
let iterator = gen();
console.log(iterator.next());
console.log(iterator.next());
console.log(iterator.next());
console.log(iterator.next());
- 代码说明:
- *的位置没有限制
- 生成器函数返回的结果是迭代器对象,调用迭代器对象的next方法可以得到yield 语句后的值
- yield相当于函数的暂停标记,也可以认为是函数的分隔符,每调用一次next方法,执行一段代码
- next方法可以传递实参,作为yield语句的返回值
2.12 Promise
-
Promise是ES6引入的异步编程的新解决方案。语法上 Promise是一个构造函数,用来封装异步操作并可以获取其成功或失败的结果
- Promise构造函数: Promise (excutor){}
- Promise.prototype.then方法;then方法的返回结果是 Promise 对象, 对象状态由回调函数的执行结果决定;如果回调函数中返回的结果是 非 promise 类型的属性, 状态为成功, 返回值为对象的成功的值;如果返回是 promise类型 对象,内部返回promise状态决定than方法返回promise状态;抛出错误,状态是失败,值为抛出的值
- Promise.prototype.catch方法;
-
代码:
//Promise基本语法
//实例化 Promise 对象
const p = new Promise(function(resolve, reject){
setTimeout(function(){
// let data = '数据库中的用户数据';
// resolve
// resolve(data);
let err = '数据读取失败';
reject(err);
}, 1000);
});
//调用 promise 对象的 then 方法
p.then(function(value){//成功执行
console.log(value);
}, function(reason){//失败执行
console.error(reason);
})
2.13 set
-
ES6提供了新的数据结构Set(集合)。它类似于数组,但成员的值都是唯一的,集合实现了iterator接口,所以可以使用『扩展运算符』和『for…of…』扩展运算符进行遍历,集合的属性和方法:
- size返回集合的元素个数
- add增加一个新元素,返回当前集合
- delete删除元素,返回boolean值
- has检测集合中是否包含某个元素,返回boolean值
- clear清空集合,返回undefined
-
代码:
//声明一个 set
let s = new Set();
let s2 = new Set(['大事儿', '小事儿', '好事儿', '坏事儿', '小事儿']);
for (let v of s2) {
console.log(v);
}
//元素个数
console.log(s2.size);
//添加新的元素
s2.add('喜事儿');
//删除元素
s2.delete('坏事儿');
//检测
console.log(s2.has('糟心事'));
//清空
s2.clear();
console.log(s2);
for (let v of s2) {
console.log(v);
}
//集合应用
let arr = [1, 2, 3, 4, 5, 4, 3, 2, 1];
//1. 数组去重
let result1 = [...new Set(arr)];
console.log(result1);
//2. 交集
let arr2 = [4, 5, 6, 5, 6];
let result2 = [...new Set(arr)].filter(item => new Set(arr2).has(item));
console.log(result2);
//3. 并集
let union = [...new Set([...arr, ...arr2])];
console.log(union);
//4. 差集
let diff = [...new Set(arr)].filter(item => !(new Set(arr2).has(item)));
console.log(diff);
2.14 map
- ES6提供了Map数据结构。它类似于对象,也是键值对的集合。但是“键”的范围不限于字符串,各种类型的值(包括对象)都可以当作键。Map也实现了iterator接口,所以可以使用『扩展运算符』和『for …of…』。进行遍历。Map的属性和方法:
- size返回Map 的元素个数
- set 增加一个新元素,返回当前Map
- get返回键名对象的键值
- has检测Map中是否包含某个元素,返回boolean值
- clear清空集合,返回undefined
//声明 Map
let m = new Map();
//添加元素
m.set('name', '河工大');
m.set('change', function () {
console.log("我们可以改变你!!");
});
let key = {
school: '大学'
};
m.set(key, ['北京', '上海', '深圳']);
2.15 class类
- ES6提供了更接近传统语言的写法,引入了Class(类)这个概念,作为对象的模板。通过class关键字,可以定义类。基本上,ES6的class可以看作只是一个语法糖,它的绝大部分功能,ES5都可以做到,新的class写法只是让对象原型的写法更加清晰、更像面向对象编程的语法而已;知识点:
- class声明类
- constructor定义构造函数初始化
- extends继承父类
- super调用父级构造方法
- static定义静态方法和属性
- 父类方法可以重写(子类不能调用父类的重名方法)
//class
class Shouji {
//构造方法 名字不能修改
constructor(brand, price) {
this.brand = brand;
this.price = price;
}
//方法必须使用该语法, 不能使用 ES5 的对象完整形式
call() {
console.log("我可以打电话!!");
}
}
let onePlus = new Shouji("1+", 1999);
console.log(onePlus);
class Phone{
//静态属性 属于类,不属于实例对象
static name = '手机';
static change(){
console.log("我可以改变世界");
}
}
let nokia = new Phone();
console.log(nokia.name);//undefined
console.log(Phone.name);//手机
class Phone{
//构造方法
constructor(brand, price){
this.brand = brand;
this.price = price;
}
//父类的成员属性
call(){
console.log("我可以打电话!!");
}
}
class SmartPhone extends Phone {
//构造方法
constructor(brand, price, color, size){
super(brand, price);// Phone.call(this, brand, price)
this.color = color;
this.size = size;
}
photo(){
console.log("拍照");
}
playGame(){
console.log("玩游戏");
}
call(){
console.log('我可以进行视频通话');
}
}
const xiaomi = new SmartPhone('小米',799,'黑色','4.7inch');
// console.log(xiaomi);
xiaomi.call();
xiaomi.photo();
xiaomi.playGame();
// get 和 set
class Phone {
get price() {//无需参数,有返回值(没写默认undefined)
console.log("价格属性被读取了");
return 'iloveyou';
}
set price(newVal) {//需要参数(否则报错),无返回值
console.log('价格属性被修改了');
}
}
//实例化对象
let s = new Phone();
// console.log(s.price);
s.price = 'free';
2.16 数值扩展
Number.EPSILON
-
JavaScript 表示的最小精度
-
EPSILON 属性的值接近于 2.2204460492503130808472633361816E-16(小于这个数认为相等)
function equal(a, b) {
if (Math.abs(a - b) < Number.EPSILON) {
return true;
} else {
return false;
}
}
console.log(0.1 + 0.2 === 0.3);//false
console.log(equal(0.1 + 0.2, 0.3)//true
二进制和八进制
- ES6提供了二进制和八进制数值的新的写法,分别用前缀0b和0o表示。
Number.isFinite()与Number.isNaN()
- Number.isFinite()用来检查一个数值是否为有限的
- Number.isNaN()用来检查一个值是否为NaN
Number.parselnt()与Number.parseFloat()
- ES6将全局方法parseInt和 parseFloat,移植到Number对象上面,使用不变。
Math.trunc
- 用于去除一个数的小数部分,返回整数部分
Number.islnteger
- Number.islnteger()用来判断一个数值是否为整数
- 值为正,返回1
- 值为0,返回0
- 值为负,返回-1
2.17 对象扩展
- ES6新增了一些object对象的方法
- object.is比较两个值是否严格相等,与「===』行为基本一致( NaN)
- Object.assign对象的合并,将源对象的所有可枚举属性,复制到目标对象(覆盖)
- Object.setPrototypeOf可以直接给实例对象的构造函数设置对象的原型
2.18 模块化
模块化的好处
- 模块化的优势有以下几点:
- 防止命名冲突
- 代码复用
- 高维护性
模块化规范产品
- ES6之前的模块化规范有:
- CommonJS => NodeJS、Browserify
- AMD => requireJS
- CMD => seaJS
ES6模块化语法
- 模块功能主要由两个命令构成: export和import
- export命令用于规定模块的对外接口(分别暴露、统一暴露、默认暴露)
- import命令用于输入其他模块提供的功能
3、ECMAScript 7新特性
3.1 Array.prototype.includes
- Includes方法用来检测数组中是否包含某个元素,返回布尔类型值
3.2 指数操作符
- 在ES7中引入指数运算符「**」,用来实现幂运算,功能与Math.pow结果相同
4、ECMAScript 8新特性
4.1 async和await
async和 await 两种语法结合可以让异步代码像同步代码一样
async函数
-
async函数的返回值为promise对象
-
promise对象的结果由async函数执行的返回值决定
- 代码:
//async 函数
async function fn(){
// 返回一个字符串
// return '尚硅谷';
// 返回的结果不是一个 Promise 类型的对象, 返回的结果就是成功 Promise 对象
// return;//(resolved undefined)
//抛出错误, 返回的结果是一个失败的 Promise
// throw new Error('出错啦!');//(rejected 对象)
//返回的结果如果是一个 Promise 对象
return new Promise((resolve, reject)=>{
resolve('成功的数据');//(resolved 对象)
// reject("失败的错误");//(rejected 对象)
});
}
await表达式
- await必须写在 async函数中
- await右侧的表达式一般为promise对象
- await返回的是promise成功的值
- await 的promise失败了,就会抛出异常,需要通过try…catch 捕获处理
- 代码:
//创建 promise 对象
const p = new Promise((resolve, reject) => {
// resolve("用户数据");
reject("失败啦!");
})
// await 要放在 async 函数中.
async function main() {
try {
let result = await p;
console.log(result);
} catch (e) {
console.log(e);
}
}
//调用函数
main();
4.2 对象方法的扩展
Object.values和Object.entries
-
Object.values()方法返回一个给定对象的所有可枚举属性值的数组
-
Object.entries()方法返回一个给定对象自身可遍历属性**[key,value]**的数(创建map)
Object.getOwnPropertyDescriptors
- 该方法返回指定对象所有自身属性的描述对象
5、ECMAScript 9新特性
5.1 Rest/Spread属性
- Rest参数(省略)与spread扩展运算符(对象合并)在ES6中已经引入,不过ES6中只针对于数组,在ES9中为对象提供了像数组一样的rest参数和扩展运算符
5.2.正则表达式命名捕获组
- ES9允许命名捕获组使用符号**『?< name>』** ,这样获取捕获结果可读性更强
- 代码:
let str = '<a href="http://www.atguigu.com">尚硅谷</a>';
//分组命名
const reg = /<a href="(?<url>.*)">(?<text>.*)<\ /a>/;
const result = reg.exec(str);
console.log(result.groups.url);//http://www.atguigu.com
console.log(result.groups.text);//尚硅谷
5.3.正则表达式反向断言
- ES9支持反向断言,通过对匹配结果前面的内容进行判断,对匹配进行筛选
- 代码:
//声明字符串
let str = 'JS5211314你知道么555啦啦啦';
//正向断言
// const reg = /\d+(?=啦)/;
// const result = reg.exec(str);
//反向断言
const reg = /(?<=么)\d+ /;
const result=reg.exec(str);
console.log(result);
5.4.正则表达式dotAll模式
- 正则表达式中点 . 匹配除回车外的任何单字符,标记『s』改变这种行为,允许行终止符出现
- 代码:
//dot . 元字符 除换行符以外的任意单个字符
let str = `
<ul>
<li>
<a>肖生克的救赎</a>
<p>上映日期: 1994-09-10</p>
</li>
<li>
<a>阿甘正传</a>
<p>上映日期: 1994-07-06</p>
</li>
</ul>`;
//声明正则
// const reg = /<li>\s+<a>(.*?)<\ /a>\s+<p>(.*?)<\ /p>/;
const reg = /<li>.*?<a>(.*?)<\ /a>.*?<p>(.*?)<\ /p>/gs;
//执行匹配
// const result = reg.exec(str);
let result;
let data = [];
while(result = reg.exec(str)){
data.push({title: result[1], time: result[2]});
}
//输出结果
console.log(data);
6、ECMAScript 10新特性
6.1 Object.fromEntries
- 代码:
//二维数组
const result1 = Object.fromEntries([
['name', 'IT'],
['xueke', 'Java,大数据,前端,云计算']
]);
console.log(result1);
//Map
const m = new Map();
m.set('name', 'ATGUIGU');
const result2 = Object.fromEntries(m);
console.log(result2);
//Object.entries ES8
const arr = Object.entries({
name: "IT"
})
console.log(arr);
6.2 trimStart 和 trimEnd
- 代码:
// trim
let str = ' iloveyou ';
console.log(str);
console.log(str.trimStart());//清除左侧空白
console.log(str.trimEnd());//清除右侧空白
6.3 Array.prototype.flat 与flatMap
- 代码:
//flat 平
//将多维数组转化为低位数组
// const arr = [1, 2, 3, 4, [5, 6]];
// console.log(arr.flat());
// const arr = [1, 2, 3, 4, [5, 6, [7, 8, 9]]];
//参数为深度 是一个数字
// console.log(arr.flat(2));//三维变一维,深度为2
//flatMap
const arr = [1, 2, 3, 4];
const result = arr.flatMap(item => [item * 10]);//flat+map
console.log(result);
6.4 Symbol.prototype.description
- 代码:
//创建 Symbol
let s = Symbol('河工大');
//获取属性
console.log(s.description);
7、ECMAScript 11新特性
7.1 类的私有属性
- 代码:
class Person {
//公有属性
name;
//私有属性
#age;
#weight;
//构造方法
constructor(name, age, weight) {
this.name = name;
this.#age = age;
this.#weight = weight;
}
intro() {
console.log(this.name);
console.log(this.#age);
console.log(this.#weight);
}
}
//实例化
const girl = new Person('晓红', 18, '45kg');
// console.log(girl.name);
// console.log(girl.#age);//报错
// console.log(girl.#weight);
girl.intro();
7.2 Promise.allSettled
- 代码:
//声明两个promise对象
const p1 = new Promise((resolve, reject) => {
setTimeout(() => {
resolve('商品数据 - 1');
}, 1000)
});
const p2 = new Promise((resolve, reject) => {
setTimeout(() => {
resolve('商品数据 - 2');
// reject('出错啦!');
}, 1000)
});
//调用 allsettled 方法
const result = Promise.allSettled([p1, p2]);//一个成功就成功
// const res = Promise.all([p1, p2]);//都成功才成功,一个失败就失败
console.log(res);
7.3 String.prototype.matchAll
- 代码:
let str = `<ul>
<li>
<a>肖生克的救赎</a>
<p>上映日期: 1994-09-10</p>
</li>
<li>
<a>阿甘正传</a>
<p>上映日期: 1994-07-06</p>
</li>
</ul>`;
//声明正则
const reg = /<li>.*?<a>(.*?)<\ /a>.*?<p>(.*?)<\ /p>/sg
//调用方法
const result = str.matchAll(reg);
// for(let v of result){
// console.log(v);
// }
const arr = [...result];
console.log(arr);
7.4 可选链操作符
- 代码:
// 可选链操作符 ?. 判断前面的值是否传入,已传入则读取后面的属性
function main(config) {
// const dbHost = config && config.db && config.db.host;
const dbHost = config?.db?.host;
console.log(dbHost);
}
main({
db: {
host: '192.168.1.100',
username: 'root'
},
cache: {
host: '192.168.1.200',
username: 'admin'
}
})
7.5 动态import 导入
- 代码:
//test.html
<button id="btn">点击</button>
<script src="./js/app.js" type="module"></script>
//app.js 获取元素
const btn = document.getElementById('btn');
btn.onclick = function(){
import('./hello.js').then(module => {
module.hello();
});
}
//hello.js
export function hello(){
alert('Hello');
}
7.6 BigInt
- 代码:
//大整形
// let n = 521n;
// console.log(n, typeof(n));//521n 'bigint'
//函数
// let n = 123;
// console.log(BigInt(n));//123n
// console.log(BigInt(1.2));//报错
//大数值运算
let max = Number.MAX_SAFE_INTEGER;
console.log(max);//9007199254740991
console.log(max + 1);//9007199254740992
console.log(max + 2);//9007199254740993
console.log(BigInt(max))//9007199254740991n
console.log(BigInt(max) + BigInt(1))//9007199254740992n
console.log(BigInt(max) + BigInt(2))//9007199254740993n
7.7 globalThis对象
- 代码:
console.log(globalThis);//输出当前全局对象