- 原文作者:David Neal
- 原文链接:What's New In JavaScript in 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 原始数据,它的数值比当前的最大值更大。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 阶段的备选提案:
- 标准化
globalThis
对象 - 动态
import()
- Legacy RegExp 功能
- import.meta
- 字符串方法
matchAll()
Object.fromEntries()
- 简洁的
JSON.stringify
- 标准化 Hashbang 用于命令行界面(CLI)应用程序
什么时候发布 ES2019
在过去的几年里, TC39一直坚持在六月发布 ECMA-262 ECMAscript 语言规范的新版本。因此我们很有可能在今年的六月份看到 ES2019 规范。
立即试用 ES2019 新功能
一些提议的语言功能已经在 JavaScript 引擎和编译器中可用。默认情况下,这些新功能有时会被禁用,但可以通过配置启用。
使用最新版本的 Node.js 进行测试
Node.js 使用 Chorme V8 JavaScript 引擎。一些备选提案的功能可以在最新版本的 Node.js中使用,因为 V8 引擎已经能够支持它们(例如Array.prototype.flat
和 String.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 ?查看一些有用的资源。
- Learn JavaScript in 2019!
- The History (and Future) of Asynchronous JavaScript
- Build a Secure Node.js Application with JavaScript Async Await Using Hapi
- Use TypeScript to Build a Node API with Express
如果你感兴趣,你可以阅读 ECMAScript 以前的版本,像 ES2015, ES2016 以及 ES2017。