加入RUN!PC粉絲團
最近新增的精選文章
 
最多人點閱的精選文章
 
 
精選文章 - 開發技術
分享到Plurk
分享到FaceBook
 
初探ECMAScript 6 (下)
文/洪坤德 2014/9/9 下午 06:45:52


接續上篇初探ECMAScript 6 (上)所提及的,ECMAScript 6對於未來開發Client端應用的程式設計者來說影響相當大,其中最重要的變革在於舊版的ECMAScript 5 並未針對模組結構及流程控制提供原生支援,大部分的Client程式設計者都習慣利用物件及函式來模擬這一類的概念;而在新版的ECMAScript 6之中已明確的規範了模組、類別及流程控制等,這對於大型的專案或者是複雜的應用提供了較為簡易開發方式。因此本文將重點擺在既有型別或物件的擴充、簡便的寫法與用法以及結構化的應用三類的特點進行說明與介紹。
ECMAScript 6 特點
EMCAScript 6大概可以條列為以下幾類,不過由於新的型別、修飾詞已於初探ECMAScript 6 (上)介紹,因此本文將就剩餘類別依序進行介紹:
 上篇
1. 新的型別、修飾詞:包含了let、const、Rest、Spread、Symbol、Map、Set、Proxy、Promises…等。
 下篇
2. 既有型別或物件的擴充:String、Number、Math、Object、Array
3. 簡便的寫法與用法: Default function parameter、For…of、Interactor、Generator、Destructuring。
4. 結構化的應用:Class、Module。
2. 既有型別或物件的擴充
(1). String的擴充
JavaScript內部對於字元的儲存使採用UTF-16,因此對於Unicode的部分字元支援通常不足,ECMAScript 6即針對這部分進行擴充,以下分別就細節進行說明:
A. Unicode表示法
為了表示超過UTF-16所能表示的文字,JavaScript提供在Unicode編碼前加上”\u”的形式表示,但是單一字節所能表達的範圍只有”\u0000”~”\uffff”。


B. CodePointAt、FromCodePoint
常見的是對於字元的誤判,由於Unicode的部分文字編碼大於0xFFFF,因此JavaScript會將其判斷成兩個字元。codePointAt這個方法主要就是用來判斷是否為Unicode的方式;fromCodePointy則是用來將Unicode轉為String。


C. Repeat、Contains、StartsWith、EndsWith
repeat提供了重複字串的功能,可以指定需重複的次數;contains則是提供字串的搜尋功能,判斷在該字串中是否具備指定的字串;startsWith則是用於判斷字串開頭是否為指定的字串,endsWith則相反,用於判斷結尾。


D. Template Strings
Template strings 使用反引號( ` )作為辨識,除了跟一般單引號( ’ )以及雙引號( ” )有相同的用法之外,還提供多行以及內嵌變數的功能,範例如下,惟內嵌變數必須用${ }包裝。


(2). RegExp
為了因應String支援Unicode的功能,正規表達式亦支援使用”\u”處理大於\uFFFF的Unicode。


另一個flag為修飾詞y (sticky)用以尋找相符合的部分,與修飾詞g不同的地方在於,g代表在剩餘的內容找得到即可,而y堅持必須要在剩下內容的第一個字元就必須符合。


(3). Number的擴充
A. 二進制與八進制
ECMAScript 6針對二進制與八進制提供了新的表示法,分別是使用前綴詞0b與0o,以提供更完整的數字表示方式。


B. EPSILON、MIN/MAX_SAFE_INTEGER、isInteger…
EPSILON、MIN/MAX_SAFE_INTEGER為Number所新提供的三個常數,EPSILON代表的是Number所能提供的最小數值;而MIN _SAFE_INTEGER及MAN_SAFE_INTEGER則代表分別代表JavaScript所能提供的最小及最大的正整數與負整數。(JavaScript是採用IEEE 754雙精度浮點格式,因此其可表示的整數分別為正負253 -1)


isInteger、isSafeInteger兩個為Number所提供的靜態方法,前者用來檢驗傳入的數值是否為整數,NaN、無限及其他都回傳false;後者則是檢驗是否為安全的整數(介於正負253 -1 之間)。另外,JavaScript中25與25.0儲存的方式相同,所以會被視為同一個值。


(4). Math的擴充
ECMAScript 6為了使Math函數能夠應付更多的數值需求,定義許多新的Method整理如下表:



(5). Object的擴充
A. Assign、is
object.assign主要是用在把可列舉的對象複製到目標對象之中:object.is則是用來比對兩者的值是否相等,若同樣為+0、-0、undefined、NaN…則回傳True。


B. __proto__、getOwnProperty、setPrototypeOf
__proto__為Object內用來存放內部prototype,不過在ECMAScript 6的規畫當中,並不允許直接存取,必須透過getOwnProperty及setPrototypeOf進行存取,藉此實作各種常用的物件。


(6). Array的擴充
A. from、of
ECMAScript 6提供了Array.from這個方法把,其他種類的集合轉變成Array,使其能夠更簡易的使用Array所提供的擴充功能;另外亦支援帶入第二個引數,可以分別針對Collection的內容進行處理。而Array.of則是為了補足Array針對單一數值無法轉換的不足。


B. copyWithin、fill
copyWithin(target, start, end = this.length)提供指定目前array的目標、起點及終點三個引數,複製成新的Array;其中end預設為原始array的長度,因此end代表為到該index前為止。而一樣是帶入三個引數的fill,則是在target帶入新值。


C. find、findIndex
find及findIndex都是在Array中分別尋找第一個符合條件的對象,差別在於find是傳回值,findIndex是傳回該對象位置;只是因為find及findIndex都是使用callback,所以必須要在callback中撰寫搜尋條件。


D. keys、values、entries
ECMAScript 6針對Array提供了三個ArrayIterator,藉由next()可依序將內容讀出,當也可以使用for…of 的方式;其中keys是對應Array的Index集合,values則是對應值,entries則包含為成對的Index 跟value。值得留意的是,ArrayIterator索回傳的都是object,回傳的值放在value之中,done則記錄著是否已經終止的Boolean值。


3. 簡便的函數寫法與用法
(1). Destructuring
Destructuring是ECMAScript 6所提供的給值的方式,一般在賦予變數值得方式為一對一宣告,而在ECMAScript 6的規範之中,允許等號的兩邊按照相同的模式進行給值。如果無法對應,則給予undefined。


(2). Tail Calls 模式
在撰寫遞迴時,每次的遞迴呼叫都會導致新的Stack frame產生,導致整個呼叫所編譯出來的Call Stack過大,而Tail Call算是一種演算法,指的是在該子程式的尾端再進行遞迴呼叫,其中當然要將所要回傳的值帶入,目的是希望藉此不必再額外產生新的Stack frame;不過必非所有的程式語言都有支援這樣特性,所以過大的數值通常都導致Stack overflow,而在未來的ECMAScript 6將會提供這樣的特性。範例程式如下,雖然目前尚未有平台可以進行測試。


(3). Arrow Function 表示法
Arrows是一種function的縮寫方式,有點像是C#的利用=>作為新的語法,可以用在expression以及句子的主體之中,不過跟一般function不同的是,關鍵字this在Arrow function中所代表的是定義function所在的對象,而非被觸發時的對象,因此要特別小心。


(4). Default Function Parameter 設定
提供Function 變數的預設值設定,與C#相似。可以提供較大的彈性使用。


(5). For Of Loops用法、Iterator協定
ECMAScript 6提供了將所有Array中的元素取出的功能,有別於in是取得Index。不過特別的是ECMAScript 6提供了一種名為Iterator的協定,只要具備這個協定的集合接能夠使用For…of將數值讀出,而Iterator有另外提供了一個next()方法,該方法會回傳一個包含value及done兩個屬性的物件;其中value代表的該對象的值,而done代表著該位置是否為終點。


(6). Generator
ECMAScript 6利用function* and yield 可簡易的創造出Generator,Generator內部可以撰寫特定的規則,當滿足該規則時,引發特定事件。不過使用Generator所回傳的是Iterator,因此必須使用next()執行。


4. 結構化的應用
(1). Classes 類
ECMAScript 6提供Class作為定義類別使用,Class之間可以利用extends進行繼承,其中所繼承的父類別可以用super call的方式初始化並取得其執行個體。類別裡面可以有constructor,而關鍵字this在此時則代表著該Class本身。


(2). Modules 模組塊
ECMAScript 6提供了modules支援,目的是為了取代常用的JavaScript module loaders ( CommonJS及AMD )。利用export和import 分別將不同js檔中的區塊進行輸出或加載,方便各js之間使用且避免彼此之間的名稱發生衝突。



結論
從上述的內容看來,ECMASCript 6 在結構化及流程控制做了很大的變革,允許Client端的應用得以更加靈活與貼近使用者,未來在Client能過運行的應用將變得更加多元。雖然距離正式版本出現的拍定還有一段時間,不過目前各家瀏覽器已支援ECMAScript 6部分特點,因此不妨在正式版本拍定之前,先熟悉ECMASCript 6相關的用法,屆時正式版本發布後還得熟悉各家瀏覽器不同的限制。對於Client端程式設計者來說,在新版的ECMASCript 6開發或提出相對應的應用,將是一大考驗亦是創造差異的一大機會。

參考資料
初探ECMAScript 6 (上)
 ECMAScript Web Site. http://www.ecmascript.org/index.php
 ECMAScript 6 Features。https://github.com/lukehoban/es6features
 ECMAScript 6 Compatibility Table。http://kangax.github.io/compat-table/es6/
 ECMAScript 6 Specification Drafts。http://wiki.ecmascript.org/doku.php?id=harmony:specification_drafts
 ECMAScript 6 support in Mozilla。https://developer.mozilla.org/en-US/docs/Web/JavaScript/ECMAScript_6_support_in_Mozilla
 Mozilla Developer Network。https://developer.mozilla.org/zh-TW/


(本文由凌群電腦提供)