赶上 ECMAScript 潮流:用现代 JavaScript 编程

前言:得益于 TC39 从2015年开始对 ECMAScript 标准采取的年更节奏,JavaScript 开发者终生学习的「梦想」得以实现。口口相传的 ES6 已经发布三年有余,而距年中 ECMAScript2018 发布也有几个月了,站在2018年末时间点上,如何赶上 ECMAScript 的潮流呢?

本文将会介绍一些ECMAScript2018标准新特性与尚在襁褓中的一些有趣提案,汇总共十个方面。

为了便于读者阅读理解,请注意本文中提到的「ECMAScript2018」等价于「ES9」,「Stage 1/2/3/4」等概念可参考TC39 定义。本文在兼容性评估上选用了「Chrome/Edge/Opera/Safari/Firefox」五类主流浏览器与「Node」运行时进行评判,完整的评估可查阅Can I use。

ECMAScript 新特性与标准提案

1. ES 模块

第一个要介绍的 ES 模块,由于历史上 JavaScript 没有提供模块系统,在远古时期我们常用多个 script 标签将代码进行人工隔离。但得益于浏览器和 Node.js 对于 ES 标准的讨论统一,现在我们可以在浏览器中直接书写 ES 模块语法。比如我们新建一个文件在其中导出一个函数,那么在中我便可以直接导入使用它。

而在浏览器中我们可以用引入 ES 模块,我们还可以引入一个 JavaScript 文件用于兼容不支持 ES 模块写法的浏览器。加上我们可以告诉浏览器预加载一些公共库与代码。

上述的写法中都用到了 mjs 后缀,然而在浏览器中引用 ES 模块这种做法并不是强制的,但在 Node 实验性新特性中 mjs 是必须的。

兼容性如下

2. 数字分隔符

给到你一串很长的数字,如何快速辨别其数值?

我们换个写法,是不是就明确了不少:

对于非十进制数值,ES 允许我们同样用下划线进行区分

然而不幸的是这仍是一个处于 Stage 2 阶段的提案,但幸好我们有 Babel。兼容性如下:

3. BigInt

在 JavaScript 中安全整数范围是多少,一下。在此之前,我们若要操作超出安全整数范围的数值,结果正确性将不被得到保证,同样的问题也曾发生在 Node 上,曾有一个 issue 直指由于 Node 会偶发性给多个文件/文件夹赋值相同 inode 数。

对于超出了 Number 能够表示的安全整数范围的整数操作,我们现在可以使用 BigInt 了。虽然有很多 polyfill 支持,但现在我们得到官方支持了。

兼容性如下:

4. Async Iterator/Generator

我们可能习惯了这样操作一段数据读取:

但好消息是 await 支持 for-each-of 了,于是我们可以这样写了:

兼容性

5. 正则匹配与字符串操作方式

现在我们来看看 dotAll 模式。字符串模版我们都用过,比如要匹配出下面的 Hello world 我们该怎么做?

我们可能会想到可以表示任意字符,但在这里不行,因为匹配不上换行符。于是我们可以这样做:

现在 ES 支持 dotAll 模式,于是我们可以这样写:

接下来要介绍的是 Name Capture,他的作用在于将从前我们需要通过下标获取的正则匹配结果通过显式命名方法进行匹配,例如原来我们这样匹配日期:

现在我们可以这样写:

对于异常复杂的正则表达式,新特性写法的优势得以体现。

第三个特性来自 Unicode 字符匹配。现在 ES 提供两种简便的匹配方式,用于匹配非二进制 Unicode 字符,而则取其相反。

以上所述几个方法的兼容性相同,当下 Edge 与 Firefox 还未支持。

第四个特性是字符串全匹配。通过 String matchall 特性,我们原来通过 while 循环匹配所有符合正则的写法可以直接通过一次性搞定:

新特性仍然处于 Stage 3,所以支持度比较感人,但社区已经有很多 polyfill 支持这种写法。

6. catch binding

正则总是让人难以理解,来说一个简单些的新特性——。现在我们可以选择性的决定 catch 是否带上入参了。

兼容性

7. trim

假设给你一串字符串,如果让你单独删除 hello 前部的空格或者尾部的空格,你会怎么做?

以前的话,你大概率得用正则来实现,而现在和两个方法便可以完成操作。

兼容性

Promise 我们都写过,假设我们 fetch 一段数据,在结果回来之前我们需要加载 loading 动画,而结果回来后不管正确还是错误我们都需要去除这段动画。在原来,我们需要将相同的逻辑写在好几个地方(观察写法):

而现在 Promise 原型方法上补充的 finally 可以给我们减少冗余代码。

兼容性

9. 对象解构

解构这个概念我们都不陌生,可能我们也一直在毫无感知的用着,但 ES2015 只给定了数组解构的标准,而直到2017年初针对对象的解构操作还处于 stage 3 阶段。

在许多情况下,对象解构能为我们提供了一个更优雅的替代方案,例如合并两个对象:

兼容性

10. Class

最后我们来聊聊 JavaScript 中的 class。首先是字段定义,不再局限于(构造)函数中,我们可以这样定义属性和静态属性:

其次是私有变量的定义与使用。在历史的长河中,JavaScript 一直缺少像其他编程语言「正规军」所有的私有变量概念,开发者长期以来都通过闭包来实现相关功能。而现在,标准赋予了 ES 这门语言拥有私有变量定义的可能性。

在使用方法上,如果需要在 class 中定义仅在类中可访问的属性,我们需要以开头定义私有变量,就像下面这样:

至今为止,主流浏览器和 Node 均未实现该特性。

私有变量的定义方式被很多开发者吐槽很「丑」,但「不幸」的是这份提案已经处于 stage 3,提案详情见https://github.com/tc39/proposal-class-fields

后记

知乎上有个问题说的是「为什么那么多公司仍然在使用JDK6?」,作者困惑于 JDK11 都已发布但很多公司还在用着老旧的 Java 版本的现状;而反观 JavaScript(ECMAScript) 生态,在 ECMAScript2018 远未定稿之时,很多开发者便得心应手的用上了新语法产出代码,很多写法可能仍处于 Stage 3。Java 和 JavaScript 不仅在关系上类似于雷锋于雷峰塔,就在对待语言标准上,两边的开发者态度也是截然相反。

ECMAScript 的征程是星辰大海,跟上 TA 的脚步。

参考

Build the future of the web with modern JavaScript

https://github.com/tc39/proposal-numeric-separator

BigInt:JavaScript 中的任意精度整数

http://2ality.com/2016/10/asynchronous-iteration.html

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

https://developers.google.com/web/updates/2017/06/object-rest-spread

个人公众号 - 微信搜索「黯晓」或扫如下二维码

知乎专栏 -初级前端工程师

生活中难免犯错,请多多指教!

  • 发表于:
  • 原文链接https://kuaibao.qq.com/s/20181125G171LG00?refer=cp_1026
  • 腾讯「云+社区」是腾讯内容开放平台帐号(企鹅号)传播渠道之一,根据《腾讯内容开放平台服务协议》转载发布内容。

扫码关注云+社区

领取腾讯云代金券