TAT.李強 Nodejs 原生支持的 ES6 特性
In 未分類 on 2016年07月04日 by view: 22,932
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.ecomenagepro.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 日

    好文章,贊

發表評論