责编 | 屠敏
序言
一个ECMAScript标准的制作过程,包含了Stage 0到Stage 4五个阶段,每个阶段提交至下一阶段都须要TC39审批通过。本文先容这些新特性处于Stage 3或者Stage 4阶段,这意味着该当很快在浏览器和其他引擎中支持这些特性。更多优质文章尽在https://github.com/ljianshu/Blog。
类的私有变量
最新提案之一是在类中添加私有变量的方法。我们将利用 # 符号表示类的私有变量。这样就不须要利用闭包来隐蔽不想暴露给外界的私有变量。
class Counter {#x = 0;#increment {this.#x++;}onClick {this.#increment;}}const c = new Counter;c.onClick; // 正常c.#increment; // 报错
通过 # 润色的成员变量或成员函数就成为了私有变量,如果试图在 Class 外部访问,则会抛出非常。现在,此特性可在最新版本的 Chrome 和 Node.js中利用。
可选链操作符
你可能碰到过这样的环境:当须要访问嵌套在工具内部好几层的属性时,会得到臭名昭著的缺点Cannot read property 'stop' of undefined,然后你就要修正你的代码来处理来处理属性链中每一个可能的undefined工具,比如:
let nestedProp = obj && obj.first && obj.first.second;
在访问obj.first.second之前,obj和obj.first 的值要被确认非(且不是undefined)。目的是为了防止缺点发生,如果大略直接的访问obj.first.second而不对obj和obj.first 进行校验就有可能产生缺点。
有了可选链式调用 ,你只要这样写就可以做同样的事情:
let nestedProp = obj?.first?.second;
如果obj或obj.first是/undefined,表达式将会短路打算直接返回undefined。
空位合并操作符
我们在开拓过程中,常常会碰着这样场景:变量如果是空值,则就利用默认值,我们是这样实现的:
let c = a ? a : b // 办法1let c = a || b // 办法2
这两种办法有个明显的弊端,它都会覆盖所有的假值,如(0, '', false),这些值可能是在某些情形下有效的输入。
为理解决这个问题,有人发起创建一个“ish”合并运算符,用 ?? 表示。有了它,我们仅在第一项为 或 undefined 时设置默认值。
let c = a ?? b;// 等价于let c = a !== undefined && a !== ? a : b;
例如有以下代码:
const x = ;const y = x ?? 500;console.log(y); // 500const n = 0const m = n ?? 9000;console.log(m) // 0
BigInt
JS在Math上一贯很糟糕的缘故原由之一是,无法精确表示大于的数字2 ^ 53,这使得处理相称大的数字变得非常困难。
1234567890123456789 123;// -> 151851850485185200000 // 打算结果丢失精度
幸运的是,BigInt(大整数)便是来办理这个问题。你可以在BigInt上利用与普通数字相同的运算符,例如 +, -, /, , %等等。
创建 BigInt 类型的值也非常大略,只须要在数字后面加上 n 即可。例如,123 变为 123n。也可以利用全局方法 BigInt(value) 转化,入参 value 为数字或数字字符串。
const aNumber = 111;const aBigInt = BigInt(aNumber);aBigInt === 111n // truetypeof aBigInt === 'bigint' // truetypeof 111 // \"大众number\"大众typeof 111n // \公众bigint\"大众
只要在数字末端加上 n,就可以精确打算大数了:
1234567890123456789n 123n;// -> 151851850485185185047n
不过有一个问题,在大多数操作中,不能将 BigInt与Number稠浊利用。比较Number和 BigInt是可以的,但是不能把它们相加。
1n < 2// true1n + 2// Uncaught TypeError: Cannot mix BigInt and other types, use explicit conversions
现在,此特性可在最新版本的 Chrome 和 Node.js中利用。
static 字段
它许可类拥有静态字段,类似于大多数OOP措辞。静态字段可以用来代替列举,也可以用于私有字段。
class Colors {// public static 字段static red = '#ff0000';static green = '#00ff00';// private static 字段static #secretColor = '#f0f0f0';}font.color = Colors.red;font.color = Colors.#secretColor; // 出错
现在,此特性可在最新版本的 Chrome 和 Node.js中利用。
Top-level await
ES2017(ES8)中的 async/await 特性仅仅许可在 async 函数内利用 await 关键字,新的提案旨在许可 await 关键字在顶层内容中的利用,例如可以简化动态模块加载的过程:
const strings = await import(`/i18n/${navigator.language}`);
这个特性在浏览器掌握台中调试异步内容(如 fetch)非常有用,而无需将其包装到异步函数中。
另一个利用场景是,可以在以异步办法初始化的 ES 模块的顶层利用它(比如建立数据库连接)。当导入这样的“异步模块”时,模块系统将等待它被解析,然后再实行依赖它的模块。这种处理异步初始化办法比当前返回一个初始化promise并等待它办理来得更随意马虎。一个模块不知道它的依赖是否异步。
// db.mjsexport const connection = await createConnection;// server.mjsimport { connection } from './db.mjs';server.start;
在此示例中,在server.mjs中完成连接之前不会实行任何操作db.mjs。
现在,此特性可在最新版本的 Chrome中利用。
WeakRef
一样平常来说,在 JavaScript 中,工具的引用是强保留的,这意味着只要持有工具的引用,它就不会被垃圾回收。
const ref = { x: 42, y: 51 };// 只要我们访问 ref 工具(或者任何其他引用指向该工具),这个工具就不会被垃圾回收
目前在 Javascript 中,WeakMap 和 WeakSet 是弱引用工具的唯一方法:将工具作为键添加到 WeakMap 或 WeakSet 中,是不会阻挡它被垃圾回收的。
const wm = new WeakMap;{const ref = {};const metaData = 'foo';wm.set(ref, metaData);wm.get(ref);// 返回 metaData}// 在这个块范围内,我们已经没有对 ref 工具的引用。// 因此,虽然它是 wm 中的键,我们仍旧可以访问,但是它能够被垃圾回收。const ws = new WeakSet;ws.add(ref);ws.has(ref);// 返回 true
JavaScript 的 WeakMap 并不是真正意义上的弱引用:实际上,只要键仍旧存活,它就强引用其内容。WeakMap 仅在键被垃圾回收之后,才弱引用它的内容。
WeakRef 是一个更高等的 API,它供应了真正的弱引用,Weakref 实例具有一个方法 deref,该方法返回被引用的原始工具,如果原始工具已被网络,则返回undefined工具。
const cache = new Map;const setValue = (key, obj) => {cache.set(key, new WeakRef(obj));};const getValue = (key) => {const ref = cache.get(key);if (ref) {return ref.deref;}};// this will look for the value in the cache// and recalculate if it's missingconst fibonacciCached = (number) => {const cached = getValue(number);if (cached) return cached;const sum = calculateFibonacci(number);setValue(number, sum);return sum;};
总而言之,JavaScript 中工具的引用是强引用,WeakMap 和 WeakSet 可以供应部分的弱引用功能,若想在 JavaScript 中实现真正的弱引用,可以通过合营利用 WeakRef 和闭幕器(Finalizer)来实现。
现在,此特性可在最新版本的 Chrome 和 Node.js中利用。
参考文章
7 Exciting New JavaScript Features You Need to Know
New JavaScript Features Coming in ES2020 That You Can Use Now
精读《What's new in javascript》
【RPU-A】新的 Top-level await 提案
如何实现 JS 真正意义上的弱引用?