tinyshare微博账号
2019年JavaScript有什么新东西 二月 19, 2019

近年来,JavaScript已一个稳定的节奏更新新的特性。如果你很好奇下一版本的JavaScript将有哪些变化,那么这篇文章就是为你准备的。

在我们讨论最新的特性之前,很重要的一点是理解新的创意是怎么成功JavaScript语言的一部分的。

JavaScript新的语言特性的过程

主导JavaScript语言规范的叫ECMAScript,ECMAScript是由ECMA国际组织在维护。ECMA是“European Computer Manufactures Association”的缩写,中文称欧洲计算机制造联合会。评审和执行规范变更的是Technical Committee 39(简称TC39)。

ECMAScript标准的改变需要经过一个标准化的流程,包括以下几个成熟的阶段:

  • Stage 0: Ideas(创意阶段)
  • Stage 1: Formal Proposals(正式提案阶段)
  • Stage 2: Drafts(起草阶段)
  • Stage 3: Candidates(候选阶段)
  • Stage 4: Approved(批准阶段)

在一个语言特性到达Stage 4之前,都不能保证它会成为ECMAScript官方语言标准的一部分。但是像V8(用于Chrome和Nodejs)和Firefox的SpiderMonkey这样的JavaScript引擎,也许会为已提案还未到达Stage 4的特性添加实验性得支持,并接受开发者们的测试和反馈。

ES2019当前候选

在写这篇文章的时候(2019.01.22)时,还没有在Stage 4的新TC39提案。然而,有一些在Stage 3的候选特性。

免责声明:因为这些候选特性在Stage 3,最终的ES2019语言规范不一定会包含所有这些候选提案。事实上,这些候提案的一部分都已经被考虑了多年了。而且,最终的实现可能看起来或用起来和当前候选提案不一样。

JavaScript Class 的改变

提出了一些针对Class的改变,包含field declarations(字段声明),private methods and fields(私有方法和字段) 和 static methods and fields(静态方法和字段)。下面的例子展示这些改变看起来的样子。

class Truck extends Automobile {
  model = "Heavy Duty"; // 共有字段声明
  #numberOfSeats = 5; // 私有字段声明
  #isCrewCab = true;
  static #name = "Truck"; // 静态私有字段声明

  // 静态方法
  static formattedName() {
    // 注意:通过“静态字段”替代“this”来获取Truck的类名
    return `This vehicle is a ${ Truck.#name }.`;
  }

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

  // 私有方法
  #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;
    }
  }
}

虽然我个人不喜欢用hash # 语法用于私有元素,希望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。

// 用于引用
const theBiggestIntegerToday = Number.MAX_SAFE_INTEGER;
// 9007199254740991

// 使用预发 'n' 声明一个 BigInt
const ABiggerInteger = 9100000000000001n;

// 使用 BigInt() 构造函数
const EvenBigger = BigInt( 9100000000000002 );
// 9100000000000002n

// 使用 一个字符串 和 BigInt() 构造函数
const SuchBigWow = BigInt( "9100000000000003" );
// 9100000000000003n

要了解更多 BigInt 的使用场景和解答,点击这里

扁平化Array 的 flat()flatMap()

如果你学过函数式编程,那你可能知道flat()flatMap()flat()是用来取出数组中的元素,或者数组的元素还是数组的元素,将它们的元素取到最小颗粒,最后返回成一个一维数组。

const nestedArraysOhMy = [ "a", ["b", "c"], ["d", ["e", "f"]]];
// .flat() 有一个可选的参数,参数表示取的数组的深度
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" ];

// map() 通常会返回一个嵌套数组作为结果
const huh = scattered.map( chunk => chunk.split( " " ) );
console.log( huh );
// [ [ "my", "favorite" ], [ "hamburger" ], [ "is", "a" ], [ "chicken", "sandwich" ] ]

// flatMap() 将返回的数组串联到了一起
const better = scattered.flatMap( chunk => chunk.split( " " ) );
console.log( better );
// [ "my", "favorite", "hamburger", "is", "a", "chicken", "sandwich" ]

更多提案的 ES2019 候选

下面列出了写这篇文章时,在Stage 3候选阶段的另外的一些语言特性。

何时发布 ES2019

最近几年来,EC39已经持续地在每年六月发布 ECMA-262 ECMAScript语言规范。这就是说,我们将在2019年的六月见到ES2019规范。

现在尝试ES2019特性

一些提案的语言特性已经可以在JavaScript引擎和类库中使用。这些特性通常默认是被禁用的,但是可以通过配置来开启使用。

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

Node.js使用Chrome V8JavaScript引擎。有一些语言候选项已经可以再最新版Node.js中使用,因为V8已经支持它们(比如:Array.prototype.flatString.prototype.trimEnd)。

你可以使用--harmony-{feature-flat}命令行选项来开启其他语言特性。想看看你的Node.js版本支持哪些flag,可以使用--v8-options选项获取一个列表。这些候选项中的一部分被标记成“in progress"。

macOS / Linux

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

Windows

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

比如,要想运行一个Node.js应用,这个应用包含了使用字段声明和静态函数的class,你可以使用下面这个CLI选项。

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

使用 Babel 7.0+ 测试

Babel是一个JavaScript类库,它可以让你使用最新的还没有被所有浏览器和环境支持的语言特性。当你写“现代化”的JavaScript时,Babel将你的代码转化成适用于老的引擎的功能相当的语法。

Babel允许使用插件的方式来支持实验性的语言特性,Babel在他们的官方库中维护了一个已支持ECMAScript提案的列表。

获取更多关于JavaScript和ES Next

想要获取更多关于JavaScript的内容?请看下面这些有用的资源。

如果有兴趣,可以阅读一下ECMAScript之前的版本,比如 ES2015,ES2016 和 ES2017。