-
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 赋值给变量也是无效的 -
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') > 123456789012345678912nBigInt 类型不建议和其他类型进行运算,还是建议先显式的类型转换一下再操作,默认的隐式类型转换并不一致,比较奇怪
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 -
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() -
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], ...] -
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 }] -
globalThis
JavaScript 在浏览器端全局的 This 是
window,但是在 Node 端,全局 This 是global; 新增的globalThis则在两种环境中均代表全局 This浏览器端
globalThis === window > trueNode 端
globalThis === global > true -
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?.() // undefinedbabel 编译后如下
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; -
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' // 0babel 编译后如下
a ?? b <!-- babel transform --> var _a; (_a = a) !== null && _a !== void 0 ? _a : b;