ES6学习笔记04

一、ES7新特性

1.1 Array.prototype.includes()

includes方法用来检测数组中是否包含某个元素,返回布尔类型值。

const mingzhu = ['西游', '三国', '水浒']

console.log(mingzhu.includes('西游'))  // true
console.log(mingzhu.includes('红楼'))  // false

它和原先的indexOf的区别在于,indexOf返回的是一个数组下标,如果不存在返回-1。

1.2 **

ES7新增了**表示求次方

console.log(2 ** 10)  // 1024
console.log(Math.pow(2, 10))  // 1024

二、ES8新特性

2.1 async

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

2.2 await表达式

  1. await必须写在async函数中
  2. await右侧的表达式一般为promise对象
  3. await返回的是promise成功的值
  4. await的promise失败了,就会抛出异常,需要通过try…catch捕获处理
// 创建promise对象
const p = new Promise((resolve, reject) => {
    resolve("用户1数据")
    // reject("失败了1!")
})

// await 要放在 async 函数中
async function main() {
    try {
        let result = await p
        console.log(result);
    } catch (e) {
        console.log(e);
    }
}
// 调用函数
main()

2.3 实例:async和await结合读取文件

const fs = require("fs");

// 读md1
function readmd1() {
 return new Promise((resolve, reject) => {
   fs.readFile("./resources/markdown1.md", (err, data) => {
     // 如果失败
     if (err) reject(err);
     // 如果成功
     resolve(data);
   });
 });
}

// 读md2
function readmd2() {
 return new Promise((resolve, reject) => {
   fs.readFile("./resources/markdown2.md", (err, data) => {
     // 如果失败
     if (err) reject(err);
     // 如果成功
     resolve(data);
   });
 });
}

// 读md3
function readmd3() {
 return new Promise((resolve, reject) => {
   fs.readFile("./resources/markdown3.md", (err, data) => {
     // 如果失败
     if (err) reject(err);
     // 如果成功
     resolve(data);
   });
 });
}

// 声明一个 async 函数
async function main() {
 // 获取md1内容
 let md1 = await readmd1();
 // 获取md2内容
 let md2 = await readmd2();
 // 获取md3内容
 let md3 = await readmd3();

 console.log(md1.toString());
 console.log(md2.toString());
 console.log(md3.toString());
}

main();

在这里插入图片描述

2.4 实例:async和await封装AJAX请求

// 发送 AJAX 请求, 返回的结果是 Promise 对象
function sendAJAX(url) {
    return new Promise((resolve, reject) => {
        // 1.创建对象
        const x = new XMLHttpRequest()

        // 2. 初始化
        x.open('GET', url)

        // 3. 发送
        x.send()

        // 4.事件绑定
        x.onreadystatechange = function () {
            if (x.readyState === 4) {
                if (x.status >= 200 && x.status < 300) {
                    // 成功了
                    resolve(x.response)
                } else {
                    // 如果失败
                    reject(x.status)
                }
            }
        }
    })
}

// promise then 方法测试
// sendAJAX("https://api.apiopen.top/getJoke").then(value => {
//     console.log(value);
// }, reason => { })

// async 与 await 测试
async function main() {
    // 发送 AJAX 请求
    let result = await sendAJAX("https://api.apiopen.top/getJoke")
    console.log(result);
}
main()

2.5 Object.values()、.keys()和entries()

  1. Object.keys()方法返回一个给定对象的所有可枚举属性键的数组
  2. Object.values()方法返回一个给定对象的所有可枚举属性值的数组
  3. Object.entries()方法返回一个给定对象自身可遍历属性[key,value]的数组
// 声明对象
const school = {
    name: 'wjr',
    study: ['es6', 'js', 'node']
}
// 获取对象所有的键
console.log(Object.keys(school));  // ['name', 'study']

// 获取对象所有的值
console.log(Object.values(school));  // ['wjr', ['es6', 'js', 'node']]

// 获取对象的所有键值对
console.log(Object.entries(school));  // [['name', 'wjr'], ['study', ['es6', 'js', 'node']]]

// entries方法可以用来创建Map
const m = new Map(Object.entries(school))
console.log(m.get('study'));  // ['es6', 'js', 'node']

2.6 Object.getOwnPropertyDescriptors

该方法返回指定对象所有自身属性的描述对象

三、ES9新特性

3.1 针对对象的spread扩展运算符

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

function connect({host, port, ...user}){
	console.log(host)
	console.log(port)
	console.log(user)
}
connect({
	host: '127.0.0.1',
	port: 3306,
	username: 'root',
	password: 'root',
	type: 'master'
)
// connect函数中接收的对象会正常接收前两个参数,而将后面的username,password,type三个参数一起存到user对象中

3.2 正则扩展-命名捕获分组group

ES9为正则匹配新增了组的概念

// 声明一个字符串
let str = '<a href="http://www.baidu.com">百度</a>'
// [未添加组]使用正则提取 url 与 文本标签
const reg1 = /<a href="(.*)">(.*)<\/a>/

// 执行
const result = reg1.exec(str)
// 输出的结果是一个数组 索引0的是整个正则匹配到的结果,1是第一个小括号匹配到的结果 2是第二个小括号匹配到的结果
console.log(result); // ['<a href="http://www.baidu.com">百度</a>', 'http://www.baidu.com', '百度']
console.log(result[1]);  // http://www.baidu.com
console.log(result[2]);  // 百度
// [添加组]使用正则提取 url 与 文本标签
const reg2 = /<a href="(?<url>.*)">(?<text>.*)<\/a>/
const result2 = reg2.exec(str)
console.log(result2);
console.log(result2.groups.text);
console.log(result2.groups.url);

在这里插入图片描述
如上图所示,可以看到明显的正则分组,并且可以将匹配到的值重新命名,使用属性的方式去获取,防止了正则变化时,数字位置变化的问题。

3.3 正则扩展-反向断言

断言:断言(Assertion)是一个对当前匹配位置之前或之后的字符的测试, 它不会实际消耗任何字符,所以断言也被称为“非消耗性匹配”或“非获取匹配”。
正向断言的意思是:当前位置后面的字符串应该满足断言,但是并不捕获,仅此而已。
反向断言和正向断言行为一样,只是方向相反,

// 声明字符串
let str = 'JS456123你知道么555啦啦啦'
// 正向断言
const reg1 = /\d+(?=啦)/
const result1 = reg1.exec(str)

console.log(result1);  // ['555']
// 反向断言
const reg2 = /(?<=么)\d+/
const result2 = reg2.exec(str)
console.log(result2);  // ['555']

3.4 正则扩展-dotAll模式

dot .:是一种元字符,可以实现匹配除换行符以外的任意单个字符。
如何使用dotAll模式:正则表达式后面增加字符s,这样表达式内的dot(.)就能匹配任意字符了。
如若要实现全局匹配,需要在s前面加个g,表示全局匹配。

let str = `
<ul>
    <li>
        <a>肖申克的救赎</a>
        <p>上映时间:1994-09-10</p>
    </li>
    <li>
        <a>阿甘正传</a>
        <p>上映时间:1994-07-06</p>
    </li>
</ul>`
// 声明正则[不用dotAll]
const reg1 = /<li>\s+<a>(.*?)<\/a>\s+<p>(.*?)<\/p>/
// 执行匹配
const result1 = reg1.exec(str)
console.log(result1);
// 声明正则[使用dotAll]
const reg2 = /<li>.*?<a>(.*?)<\/a>.*?<p>(.*?)<\/p>/gs  // g表示全局匹配,去掉则是单个匹配
// 执行全局匹配
let result2
let data = []
while (result2 = reg2.exec(str)) {
    data.push({ title: result2[1], time: result2[2] })
}
console.log(data);

在这里插入图片描述

四、ES10新特性

4.1 字符串方法扩展-trimstart()和trimend()

清除字符串左侧的空白符和清除字符串右侧的空白符。

4.2 数组方法扩展-flat()

flat()方法将多维数组转换为低维数组,参数表示深度,是一个数字

const arr = [1, 2, 3, [5, 6]]
console.log(arr.flat()) // [1, 2, 3, 5, 6]
const arr2 = [1, 2, 3, [5, 6, [7, 8]]]
console.log(arr.flat()) // [1, 2, 3, 5, 6, [7, 8]]
console.log(arr.flat(2)) // [1, 2, 3, 5, 6, 7, 8]

4.3 数组方法扩展-flatMap()

flatMap方法相当于arr.flat()和arr.map()相结合。

const arr = [1, 2, 3, 4]
const result = arr.map(item => item * 10)  // map实现对所有数据操作
console.log(result)  // 
const result1 = arr.map(item => [item * 10])  
console.log(result)  // [[10], [20], [30], [40]]
// 使用flatMap()
const result2 = arr.flatMap(item => [item * 10])
console.log(result)  // [10, 20, 30, 40]

4.4 Symbol.prototype.description

// 创建 Symbol
let s = Symbol('Eson')
console.log(s.description)  // Eson

五、ES11新特性

5.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);  // 会报错 无法输出私有属性
girl.intro();  // 小红 18 45kg

5.2 Promise.allSettled

根据选中的Promise对象,调用Promise.allSettled方法,始终返回一个reslove的Promise对象,Promise对象中的结果根据选中的Promise对象来判断是resolve还是rejected。
all和allSettled的区别:
all只有全部Promise对象都是成功才返回reslove,只要有一个失败就返回rejected,而allSettled返回的Promise对象一定是成功的,不管是否有失败的对象。
all和allSettled都在批量异步的场景下使用,如果每个异步都想要一个结果那就使用allSettled,如果每个异步任务都要求成功才能往下执行那就使用all。

// 声明两个promise对象
const p1 = new Promise((resolve, reject) => {
    setTimeout(() => {
        resolve('商品数据')
    }, 1000)
})

const p2 = new Promise((resolve, reject) => {
    setTimeout(() => {
        reject('出错拉')
    }, 1000);
})
// 调用 allsettled 方法
const result1 = Promise.allSettled([p1, p2])
const result2 = Promise.all([p1, p2])
console.log(result1);
console.log(result2);

在这里插入图片描述

5.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 reg1 = /<li>.*?<a>(.*?)<\/a>.*?<p>(.*?)<\/p>/sg
// 调用方法
const result = str.matchAll(reg1)
console.log(result);  // 返回的结果是一个可迭代对象

for (let v of result) {
    console.log(v);
}

在这里插入图片描述

// 使用扩展运算符展开
const arr = [...result]
console.log(arr);

在这里插入图片描述

5.4 可选链操作符?.

可选链操作符(?.)会先判断?前面的是否存在,存在则继续执行.后面的属性。

function main(config) {
    // 这样会存在一个问题,如果传入的参数对象为空的话就会报错
    // const dbHost = config.db.host
    // 因此根据传入的参数对象进行判断,如果参数对象存在就获取他的db属性,如果db存在就获取db中的host
    // const dbHost = config && config.db && config.db.host;
    // 使用可选链操作符能够做到一样的效果
    const dbHost = config?.db?.host
    console.log(dbHost);
}
main()  // undefined
main({
    db: {
        host: '192.168.1.100',
        username: 'root'
    },
    cache: {
        host: '192.168.1.200',
        username: 'admin'
    }
})  // 192.168.1.100

5.5 大整型

// 大整型
let n = 521n
console.log(n, typeof (n)); // 521n BigInt

// 函数
let m = 123
console.log(BigInt(m));  // 123n
// console.log(BigInt(1.2)); // 报错

// 大整型运算
let max = Number.MAX_SAFE_INTEGER   // js最大安全整数
console.log(max);  // 9007199254740991
console.log(max + 1);  // 9007199254740992
console.log(max + 2);  // 9007199254740992 出现了无法继续加的情况

// 使用大整型就能进行相关运算
console.log(BigInt(max));  // 9007199254740991n
console.log(BigInt(max) + BigInt(1));  // 9007199254740992n
console.log(BigInt(max) + BigInt(2));  // 9007199254740993n
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值