Create: August 6, 2021
Last Modify: Oct 14, 2021

ES 2020

  1. Denamic import()

    Node 13.2.0+ @babel/plugin-syntax-dynamic-import

    在这之前使用 ES6 module 导入模块,都是在文件顶部 import xxx from 'xxx',这样带来的好处有很多,譬如

    • 做静态语法分析
    • tree-shaking

    但是在某些场景,一些特性又是很有用的,这些在静态导入场景没有办法实现

    • 有选择性的 import
    • 从脚本中作为模块导入
    • 延迟加载

    现在它支持动态调用了…譬如

    if (val) {
        import("lodash").then(({ default: _ }) => {
            console.log(_.get(val, "a"));
        });
    }
    
    <!-- async 方式 -->
    async () => {
        if (val) {
            const { default: _ } = await import("lodash");
            console.log(_.get(val, "a"));
        }
    }
    

    虽然 import() 看起来像函数调用,但是在语法意义上更像是 super(),因此 import 并不继承自 Function.prototype,不存在 call、apply、bind方法,此外将 import 赋值给变量也是无效的

  2. BitInt

    BitInt 作为新增的原始数据类型(在这之前有6种: String, Number, Boolean, undefined, Object, Symbol),为了解决 JavaScript 中 Number 在范围(Number.MIN_SAFE_INTEGER - Number.MAX_SAFE_INTEGER)之外的计算不准确精度问题

    let n = Number.MEX_SAFE_INTEGER
    > 9007199254740991
    n += 1
    > 9007199254740992
    n += 1
    > 9007199254740992
    
    <!-- BigInt -->
    n = BigInt(Number.MAX_SAFE_INTEGER)
    > 9007199254740991n
    n += 1n
    > 9007199254740992n
    n += 1n
    > 9007199254740993n
    

    有一个注意点当数值在未转换成BigInt之前就已经超出JavaScript精度范围,不能直接使用BigInt来做转换

    BigInt(123_456_789_012_345_678_912)
    > 123456789012345683968n
    // 可以使用以下方法处理
    123_456_789_012_345_678_912n
    
    BigInt('123_456_789_012_345_678_912')
    > 123456789012345678912n
    

    BigInt 类型不建议和其他类型进行运算,还是建议先显式的类型转换一下再操作,默认的隐式类型转换并不一致,比较奇怪

    1n + <undefined | null>
    1n + <Number | Boolean>
    > 报错不能混用先使用显式类型转换
    1n + <Symbol>
    > 报错无法将Symbol转为数字
    1n + <String>
    > 先调用BigInt toString方法然后再与字符串相加
    1n + <Array | Object | Function>
    > 均调用toString后再相加
    

    除此之外,BigInt之间的算术运算与Number不大一致 / 运算实际是取除后的整数位部分,余数会被丢弃

    1n / 2n
    > 0n
    4n / 3n
    > 1n
    
  3. Module namespace exports

    通过 export 导出在 import 时可以直接用 * as xxx 来放到一个对象中

    // a.js
    const a = () => a + 1
    const b = () => b + 2
    export { a, b }
    // b.js
    import * as fun from 'a.js'
    fun.a()
    fun.b()
    
  4. String.prototype.matchAll()

    Node 12+

    在此之前,通过 String.prototype.match() ,当正则参数添加参数 g 时,获取到的只有匹配到的字符

    const str = 'abcdefgabcabcabc'
    str.match(/a/g)
    > ['a', 'a', 'a', 'a']
    

    使用 MatchAll 后,除了匹配到的字符串外,还能获取匹配的字符在目标字符串的索引等信息,不过通过 matchAll 拿到的结果是一个可迭代的对象

    const str = 'abcdefgabcabcabc'
    const res = []
    for(let target of str.matchAll(/a/g)) {
        res.push(target)
    }
    > [['a', index: 0, input: 'abcdefgabcabcabc', groups: undefined], ...]
    
  5. Promise.allSettled

    • Promise.allSettled() 所有 Promise 状态均变更 (fulfilled|rejected) 才结束
    const err = new Promise((resolve, reject) => {
        setTimeout(() => {
            reject('err')
        }, 500)
    })
    const delay1000 = new Promise((resolve, reject) => {
        setTimeout(() => {
            resolve('delay1000')
        }, 1000)
    })
    const delay2000 = new Promise((resolve, reject) => {
        setTimeout(() => {
            resolve('delay2000')
        }, 2000)
    })
    
    Promise.allSettled([err, delay1000, delay2000])
        .then(res => console.log(res))
        .catch(err => console.log(err))
    > [{ "status": "rejected", "reason": "err" }, { "status": "fulfilled", "value": 1000 }, { "status": "fulfilled", "value": 2000 }]
    
  6. globalThis

    JavaScript 在浏览器端全局的 This 是 window,但是在 Node 端,全局 This 是 global; 新增的 globalThis 则在两种环境中均代表全局 This

    浏览器端

    globalThis === window
    > true
    

    Node 端

    globalThis === global
    > true
    
  7. Optional chaining(可选链操作符)

    Node 14.5.0+ @babel/plugin-proposal-optional-chaining

    通常在通过 . 来取值都会遇到 target 可能为 undefined 或者 null 的情况,在这之前为保证取值过程不会报错都需要先判断一下或者借助类似于 lodash 这种工具库,现在可以以一种更优雅的方式来达到目的

    const a = { b: null, c: undefined }
    const c = a.b?.c    // undefined
    const cc = a?.c?.()  // undefined
    

    babel 编译后如下

    a?.b?.c
    <!-- babel transform -->
    var _a, _a$b;
    (_a = a) === null || _a === void 0 
        ? void 0 : (_a$b = _a.b) === null || _a$b === void 0 
        ? void 0 : _a$b.c;
    
  8. Nullish coalescing(空值合并运算符)

    Node 14.0.0+ @babel/plugin-proposal-nullish-coalescing-operator

    增加 ?? 运算符,仅当运算符左边值为 undefined 或者 null 时,返回运算符右侧变量,否则返回左侧变量

    const a = {b: null, c: 0}
    const b = a.b ?? '2333'   // '2333'
    const c = a.c ?? '2333'   // 0
    

    babel 编译后如下

    a ?? b
    <!-- babel transform -->
    var _a;
    (_a = a) !== null && _a !== void 0 ? _a : b;
    

© 2019