【译】2019 JavaScript 新玩法

2,565 阅读6分钟

What's new in JavaScript for 2019!

在过去的一些年里,JavaScript 一直凭借着新的语言特性稳定发展。如果你对 JavaScript 的下一个版本充满期待,那么这篇文章正好是为你准备的!

在我们讨论这些最新特性之前,了解那些新的想法如何成为 JavaScript 语言的一部分是至关重要的。

新特性的发展过程

简而言之,推动 JavaScript 发展的语言规范称为 ECMAScript。审查和采用语言规范变更的 ECMA 国际组织是 TC39。 ECMAScript 规范的变更需要经历一个标准化的过程,包括成熟阶段的。

  • 阶段 0:思路
  • 阶段 1:正式提案
  • 阶段 2:草案
  • 阶段 3:备选
  • 阶段 4:批准

在语言特性到达阶段 4 之前,都不能保证它将会成为官方 ECMAScript 语言规范的一部分。然而,JavaScript 引擎的实现,如 V8(由Chorme 和 Node.js 使用)和火狐的 SpiderMonkey,可能会在达到第 4 阶段之前为提议的特性增加实验性的支持,以便开发人员测试和提供反馈。

目前 ES2019 的备选特性

在这写这篇文章的时候,阶段 4 没有一个新的 TC39 提案。然而,阶段 3 却有着很多备选提案。

声明:因为这些都是阶段 3 的备选提案,最终的 ES2019 语言规范中可能不会将这些提案全部包含在内。事实上,其中一些提案多年来一直被考虑在内。而且,最终实现的提案可能和现在的备选提案在实现上会有一些出入。

对 JavaScript 类的更改

对于类有很多建议的更改,包括字段声明私有方法和字段静态方法和字段。下面是关于这些更改的例子:

class Truck extends Automobile {
  model = "Heavy Duty"; // public field declaration
  #numberOfSeats = 5; // private field declaration
  #isCrewCab = true;
  static #name = "Truck"; // static private field declaration

  // static method
  static formattedName() {
    // Notice that the Truck class name is used
    // to access the static field instead of "this"
    return `This vehicle is a ${ Truck.#name }.`;
  }

  constructor( model, seats = 2 ) {
    super();
    this.seats = seats;
  }

  // Private method
  #getBodyType() {
    return this.#isCrewCab ? "Crew Cab" : "Standard Cab";
  }

  bodyType() {
    return `${ this.#numberOfSeats }-passenger ${ this.model } ${ this.#getBodyType() }`;
  }

  get seats() { return this.#numberOfSeats; }
  set seats( value ) {
    if ( value >= 1 && value < 7 ) {
      this.#numberOfSeats = value;
      this.#isCrewCab = value > 3;
    }
  }
}

对我而言,我不喜欢用这种加 #的方式来表示私有字段。我更希望可以看到 JavaScript 语言规范采用关键字private来实现这个,毕竟其他语言也是这样。

String 的新方法 trimStart() 和 trimEnd()

String 类型有一个trim()方法,用来移除字符串首尾的空白字符。提案中trimStart()trimEnd()方法将会增加控制来删除空白字符。

const one = "      hello and let ";
const two = "us begin.        ";
console.log( one.trimStart() + two.trimEnd() ) // "hello and let us begin."

关于这种语言特性有趣的事是它已经在很多 JavaScript 引擎中被实现了。这是浏览器帮助推动语言发展的众多案例之一。

用 BigInt 来表示更大的数值

我们可能见过一个 BigInt 原始数据,它的数值比当前的最大值2^{53}更大。BigInt可以用一些不同的方式来声明。

// for reference
const theBiggestIntegerToday = Number.MAX_SAFE_INTEGER; // 9007199254740991

// use the 'n' syntax to declare a BigInt
const ABiggerInteger = 9100000000000001n;

// use the BigInt() constructor
const EvenBigger = BigInt( 9100000000000002 ); // 9100000000000002n

// use the BigInt() constructor with a string
const SuchBigWow = BigInt( "9100000000000003" ); // 9100000000000003n

阅读更多关于BigInt用例和的陷阱信息。

使用 flat() 和 flatMap() 来展开数组

如果你学习过函数式编程,那么你应该知道flat()flatMap()方法。flat()是用来获取一个数组中的值,其中有些值可能是更多数组,并返回一个新的一维数组。

const nestedArraysOhMy = [ "a", ["b", "c"], ["d", ["e", "f"]]];
// .flat() takes an optional depth argument
const ahhThatsBetter = nestedArraysOhMy.flat( 2 );
console.log( ahhThatsBetter ); // [ "a", "b", "c", "d", "e", "f" ]

flatMap()map()方法类似,但是它的回调是返回一个数组,并且最终结果将会被展示为一个一维数组而不是嵌套数组。

const scattered = [ "my favorite", "hamburger", "is a", "chicken sandwich" ];

// regular map() results in nested arrays
const huh = scattered.map( chunk => chunk.split( " " ) );
console.log( huh ); // [ [ "my", "favorite" ], [ "hamburger" ], [ "is", "a" ], [ "chicken", "sandwich" ] ]

// flatMap() concatenates the returned arrays together
const better = scattered.flatMap( chunk => chunk.split( " " ) );
console.log( better ); // [ "my", "favorite", "hamburger", "is", "a", "chicken", "sandwich" ]

更多 ES2019 的备选提案

以下是在撰写本文的时候其他第 3 阶段的备选提案:

什么时候发布 ES2019

在过去的几年里, TC39一直坚持在六月发布 ECMA-262 ECMAscript 语言规范的新版本。因此我们很有可能在今年的六月份看到 ES2019 规范。

立即试用 ES2019 新功能

一些提议的语言功能已经在 JavaScript 引擎和编译器中可用。默认情况下,这些新功能有时会被禁用,但可以通过配置启用。

使用最新版本的 Node.js 进行测试

Node.js 使用 Chorme V8 JavaScript 引擎。一些备选提案的功能可以在最新版本的 Node.js中使用,因为 V8 引擎已经能够支持它们(例如Array.prototype.flatString.prototype.trimEnd)。

你可以使用--harmony-{feature-flag}命令行选项来启用其他的语言功能。使用--v8-options指令你可以得到一个列表,上面是表示你当前使用的 Node.js 版本可以实现的一些功能。一些备选的提案被标记为“正在进行中”。

macOS / Linux

node --v8-options | grep "in progress"

Windows

node --v8-options | find "in progress"

例如,运行一个 Node.js 程序,其中包含一个使用了字段声明和静态方法的类,你可以使用下面的命令行指令。

node --harmony-class-fields --harmony-static-fields index.js

使用 Babel 7.0+ 进行测试

Babel 是一个 JavaScript 语言编译器,可以让你使用所有浏览器和环境可能尚不支持的最新语言功能。当你写“新的” JavaScript 代码的时候,Babel 将你的代码转换为旧引擎能够兼容的等效语法。

Babel使用插件支持实验性语言功能。Babel 在他们的官方资源库中维护了一个受支持的 ECMAScript 提议的列表。

了解有关的 JavaScript 和 ES 的更多信息

想要了解更多的 JavaScript ?查看一些有用的资源。

如果你感兴趣,你可以阅读 ECMAScript 以前的版本,像 ES2015, ES2016 以及 ES2017。