ES12到ES6

ES12(2021)

1、replaceAll

所有符合规则的字符都将被替换掉

const str = 'hello world'
str.replaceAll('l','')//'heo world'

2、Promise.any

Promise.any() 接收一个Promise可迭代对象,只要其中的一个 promise 成功,就返回那个已经成功的 promise 。如果可迭代对象中没有一个 promise 成功(即所有的 promises 都失败/拒绝),就返回一个失败的 promise

const promise1 = new Promise((resolve, reject) => reject('我是失败的Promise_1'));
const promise2 = new Promise((resolve, reject) => reject('我是失败的Promise_2'));
const promiseList = [promise1, promise2];
Promise.any(promiseList)
.then(values=>{
  console.log(values);
})
.catch(e=>{
  console.log(e);
});

3、WeakRefs

使用WeakRefs的Class类创建对对象的弱引用(对对象的弱引用是指当该对象应该被GC回收时不会阻止GC的回收行为)

const myWeakRef = new WeakRef({
  color: 'red',
  lenght: 25
})

myWeakRef.deref()
// => {  color: 'red', length: 25 }

myWeakRef.deref().length
// => 25

与 WeakRef 紧密相连的还有另一个功能,名为 finalizers 或 FinalizationRegistry。这个功能允许你注册一个回调函数,这个回调函数将会在对象被垃圾回收时调用。

// 创建 FinalizationRegistry:
const reg = new FinalizationRegistry((val) => {
  console.log(val)
})

(() => {
  // 创建新对象:
  const obj = {}

  //为 “obj” 对象注册 finalizer:
  //第一个参数:要为其注册 finalizer 的对象。
  //第二个参数:上面定义的回调函数的值。
  reg.register(obj, 'obj has been garbage-collected.')
})()
// 当 "obj" 被垃圾回收时输出:
// 'obj has be

4、逻辑运算符和赋值表达式

a ||= b
//等价于
a = a || (a = b)

a &&= b
//等价于
a = a && (a = b)

a ??= b
//等价于
a = a ?? (a = b)

5、数字分隔符

数字分隔符,可以在数字之间创建可视化分隔符,通过_下划线来分割数字,使数字更具可读性

const money = 1_000_000_000;
//等价于
const money = 1000000000;

1_000_000_000 === 1000000000; // true

ES11(2020)

那么ES11又引入了那些新特性呢?

\1. String 的 matchAll 方法

\2. 动态导入语句 import()

\3. import.meta

\4. export * as ns from ‘module’

\5. Promise.allSettled

\6. 新增数据类型: BigInt

\7. 顶层对象: globalThis

\8. 空值合并运算符: ??

\9. 可选链操作符:?.

1、matchAll

The matchAll method is a feature that better details regex comparisons within a string.Its result is an array that indicates the positions, as well as the string group and source of the search.See an example of a regex that allows values from 0 to 5 with the matchAll method.

matchAll() 方法返回一个包含所有匹配正则表达式的结果的迭代器。可以使用 for…of 遍历,或者使用 展开运算符(…) 或者 Array.from 转换为数组.

const regex = /[0-5]/g
const year = '2069'
const match = year.matchAll(regex)
for(const item of match){
	console.log(item)
}

//['2', index: 0, input: '2069', groups: undefined]
//['0', index: 1, input: '2069', groups: undefined]
console.log(match); // RegExpStringIterator {}
console.log([...match])

可链选操作符号:

可选链操作符( ?. )允许读取位于连接对象链深处的属性的值,而不必明确验证链中的每个引用是否有效

语法:

obj?.prop
obj?.[expr]
arr?.[index]
func?.(args)

用法示例:

let test = (config) => {
//原来我们要获取config里面的db节点的host节点数据的时候,我们可能会写如下的代码进行获取
//const dbHost = config && config.db && config.db.host;

//有了可链选操作符之后,我们可以简化成如下
const dbHost = config?.db?.host;
console.log(dbHost)
}
const config = {
  db: {
      host: '192.168.0.1',
      username: 'root'
   },
  cache: {
      host: '192.168.0.2',
      username: 'admin'
  }
};

test(config);

2、动态import()

import标准的用法导入的块是静态的,会使所有被带入的模块在加载时就编译,无法做到按需加载编译,降低了首页的加载速度。

在某些场景中,你可能希望根据条件导入模块,或者按需导入模块,这时候就可以使用动态导入代替静态导入。

在import之前,我们需要更具条件导入模块时只能使用require()

if(xxx){
const module = require('./module')
}
//现在这么写
if(xxx){
const module = import('./module')
}

@babel/preset-env 已经包含了 @babel/plugin-syntax-dynamic-import,因此如果要使用 import() 语法,只需要配置 @babel/preset-env 即可。

另外:import() 返回的是一个Promise 对象:

// module.js
export default {
  name: 'shenjp'
}

// index.js
if (true) {
  let module = import('./module.js');
  console.log(module); // Promise {<pending>
  module.then(data => console.log(data)); // Module {default: {name: "shenjp"}, __esModule: true, Symbol(Symbol.toStringTag): "Module"}
}

3、import.meta

除了动态引入模块之外,import还提供了一个元属性meta,它包含了当前引入的模块的信息。当前它里面有一个url属性,代表模块被引用的url。想引用可以使用import.meta.url,这个对象可以扩展,并且它的属性都是可写,可配置和可枚举的。

<script type="module" src="my-module.mjs"></script>

因为 import.meta 必须要在模块内部使用,如果不加 type=“module”,控制台会报错:Cannot use ‘import.meta’ outside a module。

在项目中需要下载 @open-wc/webpack-import-meta-loader 才能正常使用。

module: {
    rules: [
        {
            test: /\.js$/,
            use: [
                require.resolve('@open-wc/webpack-import-meta-loader'),
                {
                    loader: 'babel-loader',
                    options: {
                        presets: [
                            "@babel/preset-env",
                            "@babel/preset-react"
                        ]
                    },
                }
            ]
        }
    ]
}

4、exporting modules

新加了一个export的语法跟之前import的语法类似

//Existing in JS
import * as MyCom from './Co.js';
//Added in ES11
export * as MyCom from './Co.js'

5、Promise.allSettled

This attribute allows you to perform a conditional that observes whether all promises in an array have been resolved.

Promise.allSettled方法返回一个在所有给定的promise都fullfilled或者rejected后的promise并返回一个对象数组,每个对象表示对应的promise结果。

使用场景:当你有彼此不依赖的异步任务完成时,或者想知道每个promise的结果时,使用这个方法

相比较之下,promise.all()更适合做互相依赖的promise,只要有一个失败就结束

const myArrayOfPromises = [
    Promise.resolve(myPromise),
    Promise.reject(0),
    Promise.resolve(anotherPromise)
]

Promise.AllSettled(myArrayOfPromises).then ((result) => {
   // Do your stuff
  console.log(result)
/* 
    [
        { status: 'fulfilled', value: 100 },
        { status: 'rejected', reason: 'info' },
        { status: 'fulfilled', value: 'name' }
    ]
*/
})

不同点:

(1)状态

Promise.all

  1. p1和p2实例状态都为fulfilled时,p的状态才会变成fulfilled,此时p1、p2的返回值组成一个数组,传递给p的回调函数
  2. 只要p1、p2之中有一个被rejected,p的状态就变成rejected,此时第一个被reject的实例的返回值,会传递给p的回调函数

Promise.allSettled

一旦结束,状态总是fulfilled,不会变成rejected(也就是永远进不到p的catch回调)

Promise.race

其中一实例返回状态,p的状态就会发生改变,并且不会再变

(2)返回值

Promise.all

返回数组,每一个成员都是实例对应的结果

Promise.allSettled

返回数组,数组的每一个成员都是对象,每个对象都有status属性,该属性的值只可能是字符串fulfilled或字符串rejectedfulfilled时,对象有value属性,rejected时有reason属性,对应两种状态的返回值.

Promise.race

每一个实例对应的结果

(3)应用场景

Promise.all

参数Promise实例中是否有被reject的实例,无法确定所有请求都已结束

Promise.allSettled

可以确定所有请求都已结束

Promise.race

只要有返回值,立马停止其他请求

6、BigInt

BigInt 是一种数字类型的数据,它可以表示任意精度格式的整数。在此之前,JS 中安全的最大数字是 9009199254740991,即2^53-1,在控制台中输入 Number.MAX_SAFE_INTEGER 即可查看。超过这个值,JS 没有办法精确表示。另外,大于或等于2的1024次方的数值,JS 无法表示,会返回 Infinity。

BigInt 即解决了这两个问题。BigInt 只用来表示整数,没有位数的限制,任何位数的整数都可以精确表示。为了和 Number 类型进行区分,BigInt 类型的数据必须添加后缀 n.

//Number类型在超过9009199254740991后,计算结果即出现问题
const num1 = 90091992547409910;
console.log(num1 + 1); //90091992547409900

//BigInt 计算结果正确
const num2 = 90091992547409910n;
console.log(num2 + 1n); //90091992547409911n

我们还可以使用 BigInt 对象来初始化 BigInt 实例:

console.log(BigInt(999)); // 999n 注意:没有 new 关键字!!

需要说明的是,BigInt 和 Number 是两种数据类型,不能直接进行四则运算,不过可以进行比较操作。

console.log(99n == 99); //true
console.log(99n === 99); //false 
console.log(99n + 1);//TypeError: Cannot mix BigInt and other types, use explicit conversions

7、GlobalThis

对于javascript来说,不同的环境对应的全局对象的获取方式也是不同的,对于浏览器来说通常使用的是window,但是在web worker中使用的是self,而在nodejs中使用的是global。

为了解决在不同环境中的全局对象不同的问题,ES11引入了globalThis,通过这个全局对象,程序员就不用再去区分到底是在哪个环境下了,只需要使用globalThis即可。

var getGlobal = function () {
    if (typeof self !== 'undefined') { return self; }
    if (typeof window !== 'undefined') { return window; }
    if (typeof global !== 'undefined') { return global; }
    throw new Error('unable to locate global object');
};

8、空值合并运算符

新增操作符:??。当操作符左侧值为空,返回右侧值,否则返回左侧值。

const someValue = 0;
const defaultValue = 100;
let value = someValue ?? defaultValue;
//0

9、可选链操作符

操作符:?.,允许读取位于连接对象链深处的属性的值,而不必明确验证链中的每个引用是否有效。

?.操作符的功能类似于.链式操作符,不同的是,在引用为空的时候不会报错。该操作符的短路返回值是undefined

const tortoise = info.animal && info.animal.reptile && info.animal.reptile.tortoise;

因为 null.reptile 或 undefined.reptile 会抛出错误:TypeError: Cannot read property ‘reptile’ of undefined 或 TypeError: Cannot read property ‘reptile’ of null,为了避免报错,如果我们需要访问的属性更深,那么这个这句代码会越来越长。

有了可选链之后我们就可以简化

const tortoise = info.animal?.reptile?.tortoise;

10、空值合并运算符

Nullish coalescing Operator

空值有0,undefined,null,false,NaN这五个,空值合并操作符是一个逻辑操作符,当左侧操作数为null,undefined时,返回其右侧操作数,否则返回左侧操作数

与逻辑或操作符(||)不同,逻辑或操作符会在左侧操作数为假值时返回右侧操作数。也就是说,如果使用 || 来为某些变量设置默认值,可能会遇到意料之外的行为。比如为假值(例如,’’ 或 0)时。见下面的例子。

console.log(null ?? "defaultValue1")  // "defaultValue1"
console.log(undefined ?? "defaultValue2") // "defaultValue2"
console.log("" ?? "defaultValue3") // ""
console.log(0 ?? "defaultValue4")  // 0
console.log(40 ?? "defaultValue5")  // 40

||用于为变量赋默认值,但是如果左侧值为NaN,0,’’,就会导致结果不准确,

let count = 0;
let text = "";

let qty = count || 42;
let message = text || "hi!";
console.log(qty);     // 42,而不是 0
console.log(message); // "hi!",而不是 ""

空值合并操作符可以避免这种陷阱,其只在第一个操作数为nullundefined时(而不是其它假值)返回第二个操作数:

let myText = '';

let notFalsyText = myText || 'Hello world';
console.log(notFalsyText); // Hello world

let preservingFalsy = myText ?? 'Hi neighborhood';
console.log(preservingFalsy); // '' 

特点:

1、当左表达式不为 nullundefined 时,不会对右表达式进行求值。

2、不能直接与AND或OR操作符共用

null || undefined ?? "foo"; // 抛出 SyntaxError
true || undefined ?? "foo"; // 抛出 SyntaxError
//加了括号就没问题
(null || undefined ) ?? "foo"; // 返回 "foo"

Es6-es11

https://segmentfault.com/a/1190000039272641

ES10(2019)

1、Array.flat()和Array.flatMap()

flat

[1,2,[3,4]].flat(Infinity);
// [1,2,3,4]

flatMap

[1,2,3,4].flatMap(a => [a**2])
//[1,4,9,16]

2、String.trimStart()和String.trimEnd()

去除字符串首位空白字符

3、String.prototype.matchAll

为所有匹配的对象返回一个迭代器

const raw_arr = 'test1  test2  test3'.matchAll((/t(e)(st(\d?))/g));
const arr = [...raw_arr];

4、Symbol.prototype.description

只读属性,返回Symbol对象的可选描述的字符串

Symbol('mydescription').description
//'mydescription'

5、Object.fromEntries()

返回一个给定对象自身可枚举属性的健值对数组

const map = new Map(['foo','bar'],['baz',42])
console.log(Object.fromEntries(map))
//{ foo:"bar",baz:42}

6、可选catch

ES9(2018)

1、await和for…of

function getTime(seconds){
            return new Promise(resolve=>{
                setTimeout(() => {
                    resolve(seconds)
                }, seconds);
            })
        }

         

        async function test(){
            let arr = [getTime(2000),getTime(300),getTime(1000)]
            for await (let x of arr){
                console.log(x); // 2000  300 1000 按顺序的
            }
         }

        test()

2、promise.finally

Promise.resolve().then(res=> {}).finally()

3、Rest/Spread属性

const values = [1,2,3,4,5,6]
console.log(...values)
//1,2,3,4,5,6

4、正则表达式命名捕获组

允许为每一个组匹配指定一个名字,便于阅读代码,便于引用

const reg = /(?<year>[0-9]{4})-(?<month>[0-9]{2})-(?<day>[0-9]{2})/;
const match = reg.exec('2021-02-23');
console.log(match.groups) //  {year: "2021", month: "07", day: "12"}
console.log(match.groups.year) // 2021
console.log(match.groups.month) //  02
console.log(match.groups.day) //  23

5、反向断言

先了解一下正向断言:根据要匹配的字符串后面的字符进行判断和获取

// --正向断言  根据要匹配的字符串的后面的字符进行判断
    let str3 = 'hfoahfihaofhfbaidudjlajbaiduadajl88888理财'
    const reg3 = /\d+(?=理)/  // 后面的字符是理才满足条件
    const result3 = reg3.exec(str3)
    console.log(result3)

反向断言就是根据要匹配的字符串前面的字符(字符串)进行判断和获取。

    // --- 反向断言  根据要匹配的字符串的前面的字符进行判断
    let str4 = 'hfoahfihaofhfb888aidudjlajbaiduadajl88888哈哈'
    const reg4 = /(?<=b)\d+/  // b后面的字符是数字才满足条件
    const result4 = reg4.exec(str4)
    console.log(result4)
//["888",index:14,input:"hfoahfihaofhfb888aidudjlajbaiduadajl88888哈哈"]

6、正则表达式dotAll模式

dotAll(点匹配),都是匹配任意字符,但是很多字符无法匹配,如:

  • 四个字节的UTF-16的字符
  • 行终止符\n,\r换行,回车
console.log(/foo.bar/.test('foo\nbar'))
//false
console.log(/foo.bar/.test('fooabar'))
// true
//加上s可以匹配换行符,加上u可以匹配4位的utf-16字符
console.log(/foo.bar/us.test('foo\nbar'))

ES8(2017)

1、async/await

异步终极解决方案,

2、Object.values()

Object.values({a:1,b:2,c:3})
//[1,2,3]

3、Object.entries()

Object.entries({a:1,b:2,c:3})
//[["a",1],["b",2],["c,3"]]

4、String padding

//padStart

'hello'.padStart(10);//"     hello" //五个空格
'hello'.padEnd(10);// "hello     "

5、函数参数列表结尾允许逗号

6、Object.getOwnPrototypeDescriptors()

获取一个对象的所有自身属性的描述符,如果没有任何自身属性,则返回空对象

7、ShareArrayBuffer对象

SharedArrayBuffer 对象用来表示一个通用的,固定长度的原始二进制数据缓冲区,

/**
 * 
 * @param {*} length 所创建的数组缓冲区的大小,以字节(byte)为单位。  
 * @returns {SharedArrayBuffer} 一个大小指定的新 SharedArrayBuffer 对象。其内容被初始化为 0。
 */
new SharedArrayBuffer(10)

8、Atomics对象

Atomics 对象提供了一组静态方法用来对 SharedArrayBuffer 对象进行原子操作。

ES7(2016)

1、Array.prototype.includes()

[2,3,6].includes(6);//true

2、指数操作符

2**10;//2014

ES6(2015)

1、class类

class Man {
  constructor(age) {
    this.age = name;
  }
  console() {
    console.log(this.age);
  }
}
const man = new Man(100);
man.console(); //100

2、模块化ES Module

//模块a
export const sub = (a,b) => a*b
//模块b导入
import {sub} from './A'

3、箭头函数

funct = (a,v) => a*b

4、函数参数默认值

function foo(a = 'fff',b,c) {
  
}

5、模板字符串

const year = 19
const srt = `You year is ${year}`

6、解构赋值

let a = 12,b=34
let [b,s] = [a,b]//b 12 s 34

7、扩展运算符

8、对象属性简写

const name = '欧豪'
const obj = { name }

9、Promise

10、let const

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值