TAT.李强 Nodejs原生支持的ES6特性
In Node.js on 2016年07月04日 by view: 11,357
35

随着React的风靡,配合Webpack以及Babel等技术,越来越多的前端同学将ECMAScript 2015(ES6)的特性运用在项目中,import、export、class、箭头函数、块级作用域等特性屡试不爽。而对于Node.js实现的后台代码来说,我们也同样希望使用这些ES6特性,下面将以v4.4.4(LTS version)长期支持版本为例展开话题,从兼容性以及性能两方面着手分析Node.js对ES6的支持情况。

兼容性

随着io.js的引入,新版的Node.js开始原生支持部分ES6的特性,既然ES6在浏览器端使用需要通过babel等编译,在Node.js总可以放心使用了吧,然而事实并非如此。

所有的ES6特性被划分为三个级别:

  1. shipping:已经分发并默认开启的特性;
  2. staged:已经分发,但需要使用 –harmony 参数开启的特性;
  3. in progress:开发中,还不稳定或者未实现的特性,不推荐使用;

Nodejs各个版本对ES6特性的兼容列表见:http://node.green/

【shipping】

ES6特性 Nodejs兼容性
let,const,块 strict模式支持
class类 strict模式支持
Map,Set 和 WeakMap,WeakSet 支持
generators 支持
进制转换 支持
对象字面量扩展 支持
promise 支持
String对象新API 支持
symbols 支持
字符串模板 支持

这些都是Node.js原生支持的特性,除了前两个特性需要在代码前面添加’use strict’。

【staged】

  • Symbol.toStringTag
  • Array.prototype.includes
  • Rest Parameters
  • ……

可通过node –v8-options | findstr harmony进行查看。在执行带有这些特性的js代码时,需要加上–harmony参数,例如:node –harmony app.js。

【in progress】

  • harmony_modules (enable "harmony modules")
  • harmonyarrayincludes (enable "harmony Array.prototype.includes")
  • harmony_regexps (enable "harmony regular expression extensions")
  • harmonynewtarget (enable "harmony new.target")
  • ……

可通过node –v8-options | findstr "in progress"进行查看。这些特性是那些将要支持(但具体时间未知)的特性,不建议使用。

Node.js 6.x 已经支持 93% 的ES6特性

从上面分析可以看到,Node.js 4.x版本对ES6特性的原生支持并不好,但是好消息是,Node.js 6.x LTS version将要发布了,带来了性能的大幅提升、更好的测试、更完善的文档、更好的安全性,并广泛支持了ES6。

在 Node.js 5.0 发布了6个月以后,6.0的时代马上就来了,目标是替换 4.x,计划在2016年10月成为下一个LTS version(长期支持的版本),5.0 只是一个过渡版本。考虑到产品的稳定性,建议大家目前还是继续使用 Node.js 4.x,直到10月份。

Node.js 6.x 的一项重要改进是使用了V8 5.0引擎,支持了93%以上的ES6,包括 destructuring、rest 参数、class和super关键字,ES6还没有被覆盖到的只剩下一小部分,包括 direct、mutual recursion、iterator closing 等。

让我们一起期待吧!

性能

ES6是大势所趋,尽管目前Node下使用ES6仍然存在很多问题,这里还是有必要对ES6的原生性能做一下对比测试,好让大家有个量化的概念。

环境描述:

CPU:Intel(R) Core(TM)i7-4790 CPU @ 3.60GHz

RAM:16.0GB

操作系统:64bit

node版本:v4.4.4

1.块级作用域

测试代码如下:

ES5:

输出结果为45ms。

ES6:

输出结果为29ms。

可见,使用let,const声明变量的速度比var快了约55%左右。

2.class

测试代码如下:

ES5:

输出结果为2ms。

ES6:

输出结果为974ms。

可见,class没有丝毫优势,function真是快的不得了。

3.Map

测试代码如下:

ES5:

输出结果为11ms。

ES6:

输出结果为151ms。

建议如果不是必须情况,不要使用Map等复杂类型。

4.字符串模板

测试代码如下:

ES5:

输出结果为8ms。

ES6:

输出结果为50ms。

字符串模板在执行时由于会首先找出其中的模板变量,所以性能也是大不如ES5的字符串拼接。

其他特性有兴趣的同学可以一一做测试。

总结

对于ES6来说,我们不仅要了解其特性的兼容性,也要从性能上做到心中有数,从上面的测试结果可以看到,大部分ES6新特性相对ES5原生方法要慢得多,但是我依然坚信,ES6是未来的趋势,随着Node版本的更新,相信这些兼容性以及性能问题在不久的将来都将迎刃而解。

原创文章转载请注明:

转载自AlloyTeam:http://www.alloyteam.com/2016/07/nodejs-native-support-of-the-es6-features/

  1. Garyxt 2017 年 4 月 30 日

    2017-04-30
    Ubuntu 16.4 LTS 64bit 虚拟机
    内存:5.8 GiB
    CPU:Intel® Core™ i5-4570 CPU @ 3.20GHz × 4
    测试结果如下:

    ES5 BlockScope perf:18

    ES6 BlockScope perf:18

    ES5 Class perf:3

    ES6 Class perf:5

    ES5 Map perf:16

    ES6 Map perf:117

    ES5 String perf:6

    ES6 String perf:20

    • Garyxt 2017 年 4 月 30 日

      node -v 6.10.2

    • Garyxt 2017 年 4 月 30 日

      将while循环换成如下:
      // es5
      var map = {};
      while (i++ < 1000000) {
      map[i] = ‘value’;
      }
      // es6
      let map = new Map();
      while (i++ < 1000000) {
      map.set(i, ‘value’);
      }

      // 结果

      ES5 Map perf:51
      ES6 Map perf:460

      • TAT.李强 2017 年 6 月 22 日

        这类文章都有时效性的,文中也说了随着node版本的改进性能和兼容性将不是问题,当时我测试还是用的4.x的LTS版本呢,感谢回复。关于map实例比较多的情况,单一实例当时对测试没意义,可以根据自己的意愿改变测试用例,看自己需求了,只要保证es5和es6测试要点一致即可。再次感谢回复

  2. GoIn 2017 年 1 月 22 日

    ‘use strict’let i = 0;let start = +new Date(), duration; class A{ constructor() { this.name = ‘小强’; } getName(){ return this.name; }} while(i++ < 100000){ const a = new A(); a.getName();} duration = +new Date() – start;console.log(duration);Node 6.9测试为2-3mm

    • TAT.李强 2017 年 6 月 22 日

      这类文章都有时效性的,文中也说了随着node版本的改进性能和兼容性将不是问题,当时我测试还是用的4.x的LTS版本呢,感谢回复。

  3. lizzy 2016 年 12 月 14 日

  4. 临记 2016 年 11 月 26 日

    map 不应该在循环中new, map的测试应该是这样测function randomString(){ var text = “”; var possible = “ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz”; for( var i=0; i < 5; i++ ) text += possible.charAt(Math.floor(Math.random() * possible.length)); return text;}var start = +new Date(), duration;var map2 = new Map(); // var obj2 = {};for (var i=0; i < 100000; i++) { var key = randomString(); var val = randomString(); map2.set(key, val); // obj2[key] = val;}duration = +new Date() – start;console.log(duration);这样es6中map的set方法要比对object的key赋值快一倍。

  5. 游客 2016 年 11 月 26 日

    mac上除了Map之外速度并没有太大差异。

    • TAT.李强 2017 年 6 月 22 日

      node版本差异,这类文章都有时效性的,文中也说了随着node版本的改进性能和兼容性将不是问题,当时我测试还是用的4.x的LTS版本呢,感谢回复。

  6. javascript爱好者 2016 年 11 月 26 日

    这样的测试不准确,跟很多评论者一样,我怀疑是楼主的电脑配置环境导致速度差异较大,实际上即使在最低配的Macbook Air上运行你的测试,ES5和ES6时间都差不多。

    • TAT.李强 2017 年 6 月 22 日

      主要差异还是在node版本。同样环境下验证数据可能会不一致,但是问题都会暴漏出来的。

  7. xiangnaier 2016 年 11 月 17 日

    好文章

  8. Cowboy 2016 年 10 月 24 日

    Win10 64 Pro Node.js 6.9.11.块级作用域第1次 ES5: 21ms,ES6: 12ms之後 ES5: 10ms,ES6: 11ms2.ClassES5: 2ms,ES6: 3ms3.MapES5: 7ms,ES6: 75ms4.字符串模板ES5: 5ms,ES6: 14ms

    • TAT.李强 2017 年 6 月 22 日

      这类文章有时效性的,文中也说了随着node版本的改进性能和兼容性将不是问题,当时我测试还是用的4.x的LTS版本呢,感谢回复。

  9. 极乐网 2016 年 9 月 12 日

    好文章,赞!我能转到我的网站吗?http://www.dreawer.com

  10. 呵呵 2016 年 8 月 19 日

    腾讯的就这点水平?这个测试方法,无语!!!

    • 黑白头像的悲哀 2016 年 8 月 27 日

      我见过很多人这样测试,有何高招,请指教

    • TAT.李强 2017 年 6 月 22 日

      这里最后给出的数值都是跑出来的平均值,不同的环境数据可能会不一致,但是结论是一致的,取决于node版本。

  11. 洛丨小嘻 2016 年 8 月 1 日

    测试环境在mac下,时间都在10ms以内,怀疑是否windows环境造成巨大差异

    • Tony_Zixuan 2016 年 8 月 10 日

      我也是mac环境,差别不是很大,有时候ES5快过ES6也是有的

      • TAT.李强 2017 年 6 月 22 日

        这类文章时效性比较强,文中也说了随着node版本的改进性能和兼容性将不是问题,请确保node版本,当时我测试还是用的4.x的LTS版本呢,文中有特意说明node环境,感谢回复。

    • TAT.李强 2017 年 6 月 22 日

      这类文章有时效性的,文中也说了随着node版本的改进性能和兼容性将不是问题,请确保node版本,当时我测试还是用的4.x的LTS版本呢,文中有特意说明node环境,感谢回复。

  12. xingkai 2016 年 7 月 27 日

    Map Set适合处理大量数据,而不是new出好多对象…new的过程当然要慢些

    • TAT.李强 2017 年 6 月 22 日

      测试用力自己按需写就好,我的应用场景有别于你的需求。

  13. WEI 2016 年 7 月 27 日

    你们的aeditor不开源吗?求源码啊。

  14. Milo 2016 年 7 月 22 日

    es6语法很多都和java持平了~一门语言的诞生都这样大同小异么?

  15. luciy 2016 年 7 月 19 日

    测试楼主的发布的实例发现 ES5 和 ES6 代码运行时间几乎相同,是否多开几个环境测试下,保证结果准确。你这样有误导群众的嫌疑。

    • TAT.李强 2017 年 6 月 22 日

      这类文章都有时效性的,文中也说了随着node版本的改进性能和兼容性将不是问题,请确保node版本,当时我测试还是用的4.x的LTS版本呢,文中有特意说明node环境,不同的环境数据可能会不一致,但是结论是一致的,取决于node版本。感谢回复。

  16. 幻天芒 2016 年 7 月 19 日

    这种方式测试性能,并不太可取吧。比如第三条,一般场景是使用Map,然后使用它的get和set方法。应该在这里面去比较它的性能更合理些。

    • TAT.李强 2017 年 6 月 22 日

      测试用例自己按需写就好,我的应用场景有别于你的需求。

  17. WEI 2016 年 7 月 17 日

    最近发现很多H5把资源都压在一个文件里面了,能不能给点思路?

  18. 沈联民 2016 年 7 月 15 日

  19. test 2016 年 7 月 5 日

    好文章,赞

发表评论