近年来,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候选阶段的另外的一些语言特性。
- 标准化得
globalThis
对象 - 动态
import()
Legacy RegExp
特性import.meta
- 字符串
matchAll()
Object.fromEntries()
- 格式良好的
JSON.stringify
- 为CLI应用的标准化的
Hashbang
何时发布 ES2019
最近几年来,EC39已经持续地在每年六月发布 ECMA-262
ECMAScript语言规范。这就是说,我们将在2019年的六月见到ES2019规范。
现在尝试ES2019特性
一些提案的语言特性已经可以在JavaScript引擎和类库中使用。这些特性通常默认是被禁用的,但是可以通过配置来开启使用。
使用最新版本的Node.js来测试
Node.js
使用Chrome V8
JavaScript引擎。有一些语言候选项已经可以再最新版Node.js中使用,因为V8已经支持它们(比如:Array.prototype.flat
和String.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的内容?请看下面这些有用的资源。
- 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。