ECMAScript6已经于近日进入了RC阶段,而早在其处于社区讨论时,我就开始一直在尝试使用ES6进行开发的方案。在Babel推出后,基于ES6的开发也有了具体可执行的解决方案,无论是Build还是Debug都能得到很好的支持。
而在有了充足的环境、工具之后,我们面临的是对ES6众多新特性的选择和分析,以便选取一个最佳的子集,让我们可以享受ES6带来的便利(减少代码量、提高可读性等)的同时,也可以顺利运行于当前以ES3-ES5为主的浏览器环境中。
经过分析后,本文试图对ES6各个特性得出是否适合应用的初步结论,并一一解释其使用场景。ES6的特性列表选自es6features。
- ★★★ 推荐使用
- ★★ 有考虑地使用
- ★ 慎重地使用
- ☆ 不使用
特性 | 推荐程度 |
---|---|
arrows | ★★★ |
classes | ★★★ |
enhanced object literals | ★★★ |
template strings | ★★★ |
destructuring | ★★ |
default + rest + spread | ★★★ |
let + const | ★★★ |
iterators + for..of | ★★ |
generators | ★ |
unicode | ☆ |
modules | ★★ |
module loaders | ☆ |
map + set + weakmap + weakset | ★★ |
proxies | ☆ |
symbols | ★ |
subclassable built-ins | ☆ |
promises | ★★★ |
math + number + string + array + object APIs | ★★★ |
binary and octal literals | ★ |
reflect api | ☆ |
tail calls | ★★ |
接下来我们以上特性挨个进行介绍。需要关注一点:如果你不想使用shim库(如Babel的browser-polyfill.js
和generatorsRuntime.js
)或者想使用尽可能少的helper(Babel的externalHelpers
配置),那么需要按你的需求进一步缩减可使用的ES6特性,如Map
、Set
这些就不应该使用。
语法增强类
Arrow function
Arrow functions是ES6在语法上提供的一个很好的特性,其特点有:
- 语法更为简洁了。
- 文法上的固定
this
对象。
我们鼓励在可用的场景下使用Arrow functions,并以此代替原有的function
关键字。
当然Arrow functions并不是全能的,在一些特别的场景下并不十分适用,最为典型的是Arrow functions无法提供函数名称,因此做递归并不方便。虽然可以使用Y combinator来实现函数式的递归,但其可读性会有比较大的损失。
配合后文会提到的对象字面量增强,现在我们定义方法/函数会有多种方式,建议执行以下规范:
- 所有的Arrow functions的参数均使用括号
()
包裹,即便只有一个参数:
1 2 3 4 5 |
// Good let foo = (x) => x + 1; // Bad let foo = x => x + 1; |
- 定义函数尽量使用Arrow functions,而不是
function
关键字:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
// Good let foo = { bar() { // code } }; // Bad let foo = { bar: () => { // code } }; // Bad let foo = { bar: function () { // code } }; |
除非当前场景不合适使用Arrow functions,如函数表达式需要自递归、需要运行时可变的this
对象等。
- 对于对象、类中的方法,使用增强的对象字面量:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
// Good let foo = { bar() { // code } }; // Bad let foo = { bar: () => { // code } }; // Bad let foo = { bar: function () { // code } }; |
增强的对象字面量
对象字面量的增强主要体现在3个方面:
可在对象中直接定义方法
1 2 3 4 5 |
let foo = { bar() { // code } }; |
我们推荐使用这种方式定义方法。
可使用通过计算得出的键值
1 2 3 4 |
let MY_KEY = 'bar'; let foo = { [MY_KEY + 'Hash']: 123 }; |
我们推荐在需要的时候使用计算得出的键值,以便在一个语句中完成整个对象的声明。