2.重温ES6新语法特性 (下)

187 阅读6分钟

因为掘金文字长度限制,分为上下两篇: 上篇: juejin.cn/spost/74110…

虽然ES6用了很久了,但是从没有记录过相关内容,学习新增API的同时,当做温习,查漏补缺(阮一峰ES6)。

2.ES2017

name编写注意点
ES2017String1.字符串补全长度的功能
padStart(),padEnd():
- padStart(length, 'str'), padEnd():字符串头部(尾部)补全长度,'x'.padStart(5, 'ab') => ababx, 元字符长度大于参数length, 补全不生效,参数str大于length,截断超出的位数,不传入补全str,则使用空格代替,优秀用法:'09-12'.padStart(10, 'YYYY-MM-DD') => "YYYY-09-12"
函数新增1. 允许函数的最后一个参数有尾逗号 => function f(param1, param2) 提升 function f(param1, param2,)
Object新增方法1.Object.getOwnPropertyDescriptors():返回指定对象所有自身属性(非继承属性)的描述对象
- 浅拷贝实现,以obj为原型,并将obj所有属性copy:Object.create(Object.getPrototypeOf(obj),Object.getOwnPropertyDescriptors(obj))

3.Object.keys(),Object.values(),Object.entries()
- Object.keys():返回自身所有可遍历的所有属性键名数组,不含继承的
-Object.values():返回自身所有可遍历的所有value数组,不含继承的<br>-Object.entries(): 成员是参数对象自身的(不含继承的)所有可遍历(enumerable)属性的键值对数组

-Object.fromEntries(): 是Object.entries的逆向操作,将一个键值对数组转为对象 =>Object.fromEntries([['foo', 'bar'],['baz', 42]])
aysnc函数新增1.async函数就是将 Generator 函数的星号(*)替换成async,将yield替换成awaitGenerator ,就是Generator函数的语法糖。async函数返回Promise对象,可在then方法添加回调函数。当函数执行时遇到await,会先返回,知道异步操作 完成再执行后面的语句。
- sleep 实现: function sleep(time) { return new Promise((resolve, reject) => { setTimeout(resolve, time);}) }; for(let i = 1; i <= 5; i++) {console.log(i); await sleep(1000); }
- 为了防止Promise结果是rejected,最好把await放在try..catch
- 多个请求如果不是同步关系,让他们同时触发:let [foo, bar] = await Promise.all([getFoo(), getBar()]);
- async 函数的实现原理,就是将 Generator 函数自动执行器包装在一个函数里。

3. ES2018

name编写注意点
ES2018 RegExp新增方法1. s 修饰符:dotAll 模式
- 正则的(.)匹配任意单个特殊字符,但是无法匹配4字节的UTF-16字符和行终止符(U+000A 换行符(\n), U+000D 回车符(\r),U+2028 行分隔符,U+2029 段分隔符),
/foo.test/.test('foo\ntest') => false
/foo.test/s.test('foo\ntest') => true
- dotAll属性: const reg = /a.b/s; reg.dotAll => true; reg.flags => s

2.后行断言(?<=, ?<!):
- /(?<=y)x/: 匹配前面是xx,"yxdsdsdxx".match(/(?<=x)x/) => index为8的x
- /(?<=\$)\d+/: 匹配在美元符号后的数字'x$1xx$10xd$x'.match(/(?<=\$)\d+/) - 匹配前面不是xx, "yxdsdsdxx".match(/(?<!x)x/) => index为1的x

3.\p{...}和\P{...}(\P是\p的否定形式)代表一类 Unicode 字符,匹配满足条件的所有字符
-var reg =/\p{Script=Greek}/u; reg.test('π') => true: 匹配一个希腊文字母
-var reg = /^\p{Decimal_Number}+$/u; reg.test('𝟏𝟐𝟑𝟜𝟝𝟞𝟩𝟪𝟫𝟬𝟭𝟮𝟯𝟺𝟻𝟼')=> true,匹配各种字形的十进制字符
var reg = /^\p{Number}+$/u; reg.test('¹¼½ⅤⅥⅦⅧⅨⅩ㉛㉜') => true,匹配数字,甚至能匹配罗马数字
-\p{White_Space}: 匹配所有空格
- \p{Hex_Digit}:匹配十六进制字符
- /\p{Extended_Pictographic}/u: 匹配 Emoji

2. 具名组匹配:允许为每一个组匹配指定一个名字,既便于阅读代码,又便于引用
-const RE_DATE = /(?<year>\d{4})-(?<month>\d{2})-(?<day>\d{2})/;const reg = RE_DATE.exec('1999-12-31'); const { year, month, day} = reg.groups
- 利用解构赋值,替换正则:('1999-12-31').replace(RE_DATE, '$<day>/$<month>/$<year>') => '31/12/1999'
正则表达式内引用具名组匹配使用\k<组名>, \1/^(?<year>\d{4})-\k<year>-\1$/.test('1990-1990-1990') => true
Function修改1. 函数实例的toString():返回一模一样的原始代码。var f =(a, b) => {console.log(a, b);} f.f.toString(); 打印内容'(a, b) => {console.log(a, b);}'
Promise新增1.Promise.prototype.finally(): 不管 Promise 对象最后状态如何,都会执行的操作
异步遍历器 async-iterator新增1.调用遍历器的next方法,返回的是一个 Promise 对象,在then的回调函数中,则是一个具有value,done两个属性的对象。asyncIterable.next().then(({value, done}) => {})
- 异步调用。const iteratorble = createAsyncIterable(['a', 'b']); const iter=iteratorble[Symbol.asyncIterator]();const [{value: v1}, {value: v2}]=await Promise.all([iter.next(), iter.next()])

2.for await ...of: 遍历异步的 Iterator 接口。也可用于同步遍历,和for..of效果一样。
- req:异步读取数据,当异步reject会报错,使用try..catch,try {for await(const data of req){ body += data;}}catch(e){}

3.异步Generator函数:async函数Generator 函数的结合。async function * aysncGenerator() { const result = await fetch('url'); yield await result.text(); } ,调用遍历器:var gener=aysncGenerator(); gener.next().then((value, done)=> {})

4.yield*: 也可以跟一个异步遍历器。async function * gen1() {yield 'a'; yield 'b';} for await(const x of gen1()) { console.log(x);}

4 .ES2019

name编写注意点
ES2019String1. 消除空格:对字符串头部(或尾部)的 tab 键、换行符等不可见的空白符号也有效
trimStart(): 消除字符串头部的空格,
trimEnd():消除字符串尾部部的空格
Function修改try catch 可省略err。之前try{}catch(err){}, 现在try{}catch{}
ES6引入类型Symbol新增1.新增description属性,返回描述值:const s = Symbol('desc'); s.description // desc

4 .ES2020

name编写注意点
ES2020RegExp1. String.prototype.matchAll()一次取出所有匹配,返回迭代器
const string = 'test1test2test3';const regex = /t(e)(st(\d?))/g;for (const match of string.matchAll(regex)) {console.log(match);}
ES2020Number1. BigInt 只用来表示整数,没有位数的限制,任何位数的整数都可以精确表示, 数据必须添加后缀ntypeof 123n => bigint,有正负号-42n
- let a = 1234n
- 可以使用各种进制表示,都要加上后缀n ,let a= 0o777n;
- BigInt 函数: let a = new BigInt(192);
- 其他方法:BigInt.asUintN(width, BigInt),BigInt.asIntN(width, BigInt), BigInt.parseInt(string[, radix])
ES2020运算符拓展新增1.链判断运算符?.,判断左侧是否是undefined或者null:const obj = message?.body?.content;,可用于obj?.prop属性、obj?.[expr]属性、 func?.(...args)函数或方法
2.Null 判断运算符??,只有运算符左侧的值为null或undefined时,才会返回右侧的值,与||的区别:它只检查null或undefined,||只要左侧是假值都会返回右边。例如 NaN || 'hello' => 返回hello, NaN ?? 'hello' => 返回NaN
Promise新增1.Promise.allSettled(): 等到一组异步操作都结束了,不管每一个操作是成功还是失败,再进行下一步操作。Promise.all()只适合所有异步都成功的情况,无法满足一个失败继续执行的。Promise.allSettled()数组的每个成员都是一个 Promise 对象,并返回一个新的 Promise 对象。只有等到参数数组的所有 Promise 对象都发生状态变更(不管是fulfilled还是rejected),返回的 Promise 对象才会发生状态变更。
module新增1.导出方法: export * as ns from 'mod';等价与import * as ns from 'mod'; export ns;

2.import()函数:importexport命令只能在模块的顶层,不能在代码块之中(比如,在if代码块之中,或在函数之中)。而引入import()函数支持动态加载模块,返回Promise对象。button.addEventListener('click', () => {import('./x.js').then(...); }]),任何地方可调用,if条件表达式,动态模块加载地方等都可以调用。

3.import.meta:返回当前模块的元信息。只能在模块内部调用。import.meta.url:当前模块的 URL 路径。import.meta.scriptElement: 是浏览器特有的元属性,返回加载模块的那个<script>元素,相当于document.currentScript属性

4 .ES2021

name编写注意点
数值新增内容1. 允许每三位添加一个分隔符(_),不能放在数值最前或最后,分隔符不能多个链接,小数点后不能有分隔符,科学计数法e前后不能有分隔符:
let num = 1_000_000; num === 10 ** 6; => true
小数可使用:let a = 0.022_122;
科学计数法:let a = 1e10_000
对象新增内容1.AggregateError错误对象:AggregateError 在一个错误对象里面,封装了多个错误。如果某个单一操作,同时引发了多个错误,需要同时抛出这些错误,那么就可以抛出一个 AggregateError 错误对象,把各种错误都放在这个对象里面
ES2021运算符拓展新增1.新增三个逻辑运算符:
- 新增 ||=,: x ||= y: 等价x || (x=y)
-新增&&=: x&&=y等价x && (x=y)
-新增??=: x??=y等价x ?? (x=y)
-用处,为遍历设置默认属性:user.id ||=1
Set和Map新增1,WeakRef:用于直接创建对象的弱引用。WeakRef 实例对象有一个deref()方法,如果原始对象存在,该方法返回原始对象;如果原始对象已经被垃圾回收机制清除,该方法返回undefined。let target = {}; let wr = new WeakRef(target); let obj= wr.deref(); if (obj){} // obj存在,target 未被垃圾回收机制清除。标准规定,一旦使用WeakRef()创建了原始对象的弱引用,那么在本轮事件循环(event loop),原始对象肯定不会被清除,只会在后面的事件循环才会被清除

2.清理器注册表功能FinalizationRegistry:用来指定目标对象被垃圾回收机制清除以后,所要执行的回调函数。
- 实例化:本身有一个参数heldValue: const registry = new FinalizationRegistry(heldValue => {});
- 注册所要观察的目标对象,参数一,要观察的对象,一旦该对象被垃圾回收机制清除,注册表就会在清除完成后,调用早前注册的回调函数,并将 some value作为参数(前面的heldValue)传入回调函数:registry.register(theObject, "some value",theObject);
- 参数3:必须是对象,一般都用原始对象。接着,再使用注册表实例对象的unregister()方法取消注册。registry.unregister(theObject);
Promise新增1.Promise.any([p1,p2,p3]):参数数组包含三个 Promise 操作。其中只要有一个变成fulfilled,返回的 Promise 对象就变成fulfilled。如果所有三个操作都变成rejected就会抛出错误

5 .ES2022

name编写注意点
ES2022 RegExp新增1. d 修饰符:正则匹配索引,exec()、match()的返回结果添加indices属性,在该属性上面可以拿到匹配的开始位置和结束位置
- const text = 'zabbcdef';const re = /ab+(cd(ef))/d;const result = re.exec(text); => result.indices // [ [1, 8], [4, 8], [6, 8] ], 匹配出ef, cdef, abcdef 三组index
数组新增1.findLast()和findLastIndex():同find和findIndex一样,只不过从最后一个成员依次往前检查

2. at(index): 返回索引位置的值,支持负索引。
对象新增内容1.Error 对象的 cause 属性,可以在生成错误时,添加报错原因的描述:const actual = new Error('an error!', { cause: 'Error cause' });

2.Object.hasOwn(): javascript属性分为自身属性和继承属性,该方法用于判断是否是自身属性,const foo = Object.create({ a: 123 }); Object.hasOwn(foo, 'a') // a是继承属性
async 函数update1.早期的语法规定是await命令只能出现在 async 函数内部,否则都会报错,现在允许在模块的顶层独立使用await命令,使得上面那行代码不会报错了。它的主要目的是使用await解决模块异步加载的问题,注意顶层await只能用在 ES6 模块。const strings = await import('/i18n/${navigator.language}');
class属性的新写法新增之前定义在constructor()方法里面的this上面:class P{constructor(){this.x=10}}; 现在可写在最顶层:class P{_x = 10; constructor(){}}
class新增或修改1.添加了私有属性,方法是在属性名之前使用#表示:class P { #props=10; get p(){return this.#props;}} const p = new P(); p.p;// 10 ,但是p.#props报错 (注意,从 Chrome 111 开始,开发者工具里面可以读写私有属性,不会报错,原因是 Chrome 团队认为这样方便调试。),私有属性也可以有getter和setter方法,也可以加static关键字。

2.改进了in运算符,使它也可以用来判断私有属性。class P {#a=10; static isA(o) { return #brand in o; }} var a = new P(); P.isA(a);

3.静态块(static block:允许在类的内部设置一个代码块,在类生成时运行且只运行一次,主要作用是对静态属性进行初始化。允许有多个静态块,每个静态块中只能访问之前声明的静态属性。另外,静态块的内部不能有return语句。class P { static a=10; static { // 只执行一次的初始化内容}}

5 .ES2023

name编写注意点
数组新增1.toReversed()-对应reverse(),颠倒数组成员的位置,toSorted()-对应sort(),对数组成员排序,toSpliced()-对应splice(),在指定位置,删除指定数量的成员,并插入新成员,with():对应splice(index, 1, value),用来将指定位置的成员替换为新的值: 他们对数组进行操作时,均不改变原数组,而返回一个原数组的拷贝
运算符的拓展新增1.#!命令:写在脚本文件或者模块文件的第一行,Unix 命令行就可以直接执行脚本,JavaScript将忽略 这一行
- 文件hello.js第一行#!/usr/bin/env node ,命令行输入:./hello.js

6. ES2024

name编写注意点
RegExpES20241. v 修饰符:Unicode 属性类的运算
1.[A--B]: 差集运算(A 减去 B)。[\p{Decimal_Number}--[0-9]] 或者 [\p{Emoji}--\p{ASCII}], : 十进制字符去除 ASCII 码的0到9
- /[\p{Decimal_Number}]/u.test('0') => true, /[\p{Decimal_Number}--[0-9]]/v.test('0') => false, 因此排除了十进制的数

2.[A&&B]:交集运算(A 与 B 的交集)
- var reg = /[\p{Emoji}&&\p{ASCII}]/u; reg.test(':-)123213') => true
StringES20241.isWellFormed() 方法:返回一个表示该字符串是否包含单独代理项

2.toWellFormed() 方法:返回一个字符串,其中该字符串的所有单独代理项都被替换为 Unicode 替换字符 U+FFFD
Object20241.groupBy(): 用于数组,返回普通对象。const fruits = [{ name: "Apple", color: "red" },{ name: "Apple", color: "purple" } ]; const result = Object.groupBy(fruits, f => f.color); result.hasOwnProperty('red') =>出错,注意,使用Object.groupBy方法返回一个没有原型(即没有继承任何属性和方法)的对象。这意味着该对象不会继承Object.prototype上的任何属性或方法,例如没有hasOwnProperty或toString等,不能使用。
Map20241.groupBy(): 作用于数组,返回为Map结构。const fruits = [{ name: "Apple", color: "red" },{ name: "Apple", color: "purple" } ]; const result = Map.groupBy(fruits, f => f.color); result.hasOwnProperty('red') =>出错
PromiseES2024Promise.withResolvers: 返回一个对象,其包含一个新的 Promise 对象和两个函数,用于解决或拒绝它,对应于传入给 Promise() 构造函数执行器的两个参数。const { promise, resolve, reject } = Promise.withResolvers(); setTimeout(() => resolve('成功!'), 8000); setTimeout(() => reject('失败'), 8000);

7. ES2025

name编写注意点
Set 与Map新增1.新增Set集合运算方法:交集intersection(other),并集union(other),差集difference(other),对称差集——返回两个集合的所有独一无二成员的集合返回两个集合的所有独一无二成员的集合symmetricDifference(other),是否为子集——任何集合都是自身的子集isSubsetOf(other),是否为超集——表示第一个集合是否为第二个集合的超集,即第二个集合的所有成员都是第一个集合的成员isSupersetOf(other), 是否不相交——判断两个集合是否不相交,即没有共同成员isDisjointFrom(other)

8.提案

name编写注意点
数组提案1.group(),groupToMap(): 将数组按照一定规则进行分组,就行SQL一样。const array = [1, 2, 3, 4, 5];array.group((num, index, array) => return num % 2 === 0 ? 'even': 'odd';);, groupToMap()作用一样,只是返回的是Map结构数据。
Promise提案1.Promise.try:为所有操作提供了统一的处理机制,不论是同步还是异步方法,只要想用then方法管理流程,最好都用Promise.try包装一下

相关地址