[譯]Node中的ES6特性


原文:http://dailyjs.com/2012/10/15/preparing-for-esnext/


Brendan Eich在Harmony之夢實現了一文中,講了一些Firefox已經實現的ES6新特性.令Node開發者興奮的是,V8也實現了其中不少的特性.

如何知道自己使用的Node支持哪些新特性:首先查看process.versions的值,

~  node -e 'console.log(process.versions)'
{ http_parser: '1.0',
node:
'0.8.12',
v8:
'3.11.10.22',
ares:
'1.7.5-DEV',
uv:
'0.8',
zlib:
'1.2.3',
openssl:
'1.0.0f' }

知道了V8的版本號,就可以在V8的更新日志中查找到該版本具體添加了哪些新特性.下面列出了Node目前支持的ES6特性:

  • 塊級作用域
  • typeof null等於"null"
  • letconst
  • Map和WeakMap
  • 模塊
  • 代理

Harmony相關選項

運行命令node --v8-options可以顯示出所有與V8相關的選項:

--harmony_typeof: 激活harmony中typeof的新特性(typeof null等於"null").(譯者注:相關提案已被拒絕,該選項未來應該會被刪除)

--harmony_scoping: 激活harmony中的塊級作用域

--harmony_modules: 激活harmony中的模塊

--harmony_proxies: 激活harmony中的代理(譯者注:和網絡中的代理服務器沒有任何關系)

--harmony_collections: 激活harmony中的集合類型(Set,Map,WeakMap)

--harmony: 激活上面所有的harmony特性(除了typeof)

只需要在運行腳本的時候加上所需選項即可:

node --harmony script.js

例子: typeof

--harmony_typeof選項比較特殊,因為它沒有被包含在--harmony中.這很有可能是因為harmony:typeof_null這項提案被拒絕了的原因.很多提案中的特性都有可能在規范完成之前被拒絕掉,如果你不確定某個特性目前的狀態,最好的辦法就是在ECMAScript DokuWiki上進行搜索.

如果啟用了該選項,typeof null === "null" 會返回true.

例子: 類型檢查

在沒有使用--harmony選項的情況下,Node也支持ES6特性Number.isNaNNumber.isFinite,可是還不支持Number.toIntegerNumber.isInteger.

isNaN("x")              //true,"x"會被轉換成NaN
Number.isNaN("x")       //false
isFinite("1")           //true,"1"會被轉換成1
Number.isFinite("1")    //false

例子:塊級作用域

ES5中的嚴格模式修復了JavaScript一個重大的設計缺陷:缺失var的賦值語句會創建一個全局變量.ES6更進了一步,引入了可以創建塊級作用域變量的let.下面的例子必須使用命令node --use-strict --harmony來運行:

for (let i = 0; i < 3; i++) {
console.log(
'i:', i);
}

console.log(i);

最后的語句console.log(i),會拋出一個ReferenceError異常.因為變量i不存在於for語句外的作用域中.而且,假如你忘記了寫let,也不會誤創建一個全局變量,因為我們啟用了嚴格模式,那樣只會拋出ReferenceError異常.和let一樣,用const定義的常量也擁有塊級作用域.

例子: 集合

ES6添加了幾個新類型來存儲集合數據: Map, Set,和WeakMap. Map類型允許將任意對象值或原始值映射到另一個值上.聽起來像普通的對象,因為我們以前總用普通的對象來實現Map本來該做的事.千萬別混淆,它們是有區別的:

var assert = require('assert')
, m
= new Map()
, key
= { a: 'Test' }
, value
= 'a test value' ; m.set(key, value); assert.equal(m.get(key), value);

這個例子表明了,map中的鍵是不會被轉換成字符串的,而對象會.

Node已經支持了Set類型,但目前還不能通過向構造函數傳入一個二維數組來進行set的初始化,也還不支持Set.prototype.size方法.

var assert = require('assert')
, s
= new Set()
;

s.add(
'a');

assert.ok(s.has(
'a'));

WeakMap是一種擁有弱引用的map.因為WeakMap保持着對一個對象的弱引用,所以它的鍵不能被遍歷(譯者注:我的理解是,因為這個鍵指向的對象有可能已經不存在了,弱引用的意思就是只保存一個標識符或者說內存地址,那個內存地址的值是什么並不關心).優點是,當沒有其他值引用這個鍵所引用的對象時,垃圾回收器會清除那個對象.

WeakMap更節約內存,復雜度比O(n)還低.

Andy E去年發表過一篇文章:ES6 – a quick look at Weak Maps,談到了WeakMap對jQuery中的expando屬性的影響.

我嘗試創建過一些擁有循環引用的WeakMap實例,然后通過gc()強制執行垃圾回收(需要添加選項node --harmony --expose_gc),但是很難檢測出那些應該被垃圾回收的對象是否真的被刪除了:

代理

貌似Node目前實現的是舊的代理API,所以我認為還沒必要去研究它.新的代理API還沒有實現,因為我沒有在郵件列表或相關資料上看到任何消息.

生成器,類,宏

目前V8還不支持生成器(Generator), 類(class)以及宏(macro).這些特性仍處於激烈的討論當中,你可以在ECMAScript DokuWiki上了解詳情:

Andreas Rossberg說過V8的工程師還不打算實現生成器.

如果你現在就想嘗試一下宏,可以試試Mozilla最近發布的sweet.js (GitHub: mozilla / sweet.js, License: BSD, npm: sweet.js).這是一個命令行工具,可以將你寫的腳本"編譯"為JavaScript,類似於CoffeeScript.

解構(Destructuring)也已經被添加到了ECMAScript 6規范草案中.

所有的ES6 shim都沒有包含這些特性,因為有些特性是無法用舊版的ECMAScript腳本實現的.

參考


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM