node12&chrome中7个新的提案功能

JavaScript(或ECMA script)是一种不断发展的语言,有许多关于如何更好发展的建议和想法。TC39(技术委员会39)是负责定义JS标准和特性的委员会,今年他们一直很活跃。以下是目前处于"第3阶段"的一些提案的摘要,这是在"完成"之前的最后一个阶段。这意味着这些功能应该很快就会在浏览器和其他引擎中实现。事实上,其中一些现在可用。

1. 私有字段 #

Chrome & NodeJS 12 中可用

是的,你没有看过。最终,JS在类中获取私有字段。不再需要this._doPrivateStuff(),定义闭包来存储私有值,或者使用WeakMap来hack私有props。

语法看起来像下面这样:

// 私有字段必须使用'#'开头
// 并且不可以在类这个块的外面去访问

class Counter {
  #x = 0;

  #increment() {
    this.#x++;
  }

  onClick() {
    this.#increment();
  }

}

const c = new Counter();
c.onClick(); // works fine
c.#increment(); // error

提案:https://github.com/tc39/proposal-class-fields

2. 可选的链?.

以前必须访问嵌套在对象内的几个级别的属性,并得到臭名昭著的错误Cannot read property 'stop' of undefined。然后更改代码以处理链中的每个可能是undefined的对象,例如:

const stop = please && please.make && please.make.it && please.make.it.stop;

// 或可以使用像'object-path'这样的库
const stop = objectPath.get(please, "make.it.stop");

通过可选的链接,你就可以像下面这样来处理:

const stop = please?.make?.it?.stop;

提案:https://github.com/tc39/proposal-optional-chaining

3. null合并 ??

变量的可选值可能缺失,如果丢失,则使用默认值,这样属于很常见的现象:

const duration = input.duration || 500;

||的问题是它将覆盖所有falsy值,如(0, '', false),在某些情况下可能是有效的输入。

键入null合并运算符,他只会覆盖undefinednull

const duration = input.duration ?? 500;

提案:https://github.com/tc39/proposal-nullish-coalescing

4. BigInt 1n

Chrome & NodeJS 12 中可用

JS一直不擅长数学的一个原因是我们无法可靠地存储大于2 ^ 53的数,这使得处理相当大的数非常困难。幸运的是,BigInt是一个解决这个特定问题的提案。

闲话少说,show me your code:

// 可以定义 BigInt 通过追加 'n' 到一个数字字面量
const theBiggestInt = 9007199254740991n;

// 对字面量使用构造函数
const alsoHuge = BigInt(9007199254740991);

// 或者对字符串使用
const hugeButString = BigInt('9007199254740991');

你还可以在BigInt上使用与普通数字相同的运算符,例如:+-/*%,…不过有一个问题,在大多数操作中不能将BigInt与数字混合使用。比较NumberBigInt工作方式,但不能添加他们:

1n < 2 
// true

1n + 2
// 🤷‍♀️ Uncaught TypeError: Cannot mix BigInt and other types, use explicit conversions

译:根据上面的报错提示,你可以改为显示的转换

Number(1n) + 2

提案:https://github.com/tc39/proposal-bigint

5. static 字段

Chrome & NodeJS 12 中可用

这个很简单。它允许在类上有一个静态字段,类似于大多数OOP语言。静态字段可以作为枚举的替代,它们也可以用于私有字段。

class Colors {
  // public static fields
  static red = '#ff0000';
  static green = '#00ff00';

  // private static fields
  static #secretColor = '#f0f0f0';

}


font.color = Colors.red;

font.color = Colors.#secretColor; // Error

提案:https://github.com/tc39/proposal-static-class-features

6. 顶层 await

chrome中可用

允许在你代码的顶层使用await。这对于调试浏览器控制台中的异步内容(如fetch)非常有用,而无需将其封装在async函数中。

如果你需要复习异步并等待,请看我在这篇文章里对他的解释

另一个致命的用例是,它可以在以异步方式初始化的ES模块的顶层使用(比如建立连接的数据库层)。当import这样的“异步模块”时,模块系统将在执行依赖它的模块之前等待它解析。这将使处理异步初始化比当前返回初始化promise并等待它的工作区容易得多。模块将不知道它的依赖关系是否是异步的。

// db.mjs
export const connection = await createConnection();
// server.mjs
import { connection } from './db.mjs';

server.start();

在此示例中,在db.mjs中完成连接之前,不会在server.mjs中执行任何操作。

提案:https://github.com/tc39/proposal-top-level-await

7. WeakRef

Chrome & NodeJS 12 中可用

对象的弱引用是不再能够使对象保持活的引用。每当我们使用(constletvar)创建一个变量时,只要该变量的引用仍然可访问,垃圾收集器(GC)就永远不会从内存中删除该变量。这些都是强引用。但是,如果没有对弱引用引用的对象有强引用,则GC可以在任何时候删除它。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 missing
const fibonacciCached = (number) => {
  const cached = getValue(number);
  if (cached) return cached;
  const sum = calculateFibonacci(number);
  setValue(number, sum);
  return sum;
};

对于缓存远程数据来说,这可能不是一个好主意,因为远程数据从内存中删除 不可预测。在这种情况下,最好使用类似LRU缓存的东西。

译:LRU缓存,是否有去了解?或者下次一起了解下 Implementing LRU cache in JavaScript -- medium

LRU cache implementation in Javascript -- stackoverflow

提案:https://github.com/tc39/proposal-weakrefs

就是这样。我希望你和我一样会兴奋地使用这些很酷的新功能。有关这些提案以及我未提及的其他提案的更多详细信息,请保持关注github上的TC39提案

原文:7 Exciting New JavaScript Features You Need to Know

Last updated