【在主畫面加入捷徑】
       
【選擇語系】
繁中 简中

[書籍回顧] Practical ES6 評價

REVIEW
【分享本文】
Facebook Twitter LinkedIn LINE Skype EverNote GMail Yahoo Email
【贊助商連結】

    前言

    Practical ES6 是 SitePoint 所出版的 the Modern JavaScript Collection 套書中的第一本。該套書共有四本:

    JavaScript 已經問世 20 多年了,在這段時間內,JavaScript 和網頁技術產生許多的變化。該系列書籍期望能帶來到西元 2018 年為止的最新實務。Practical ES6 注重的是 JavaScript 語法本身,至於工具鏈或其他的部分,則要參考該系列其他的書籍。

    本書共 221 頁,分為 19 章,算是一本輕量級的書籍。我們接下來會逐一介紹各章節。有些讀者可能會想到有些瀏覽器並未完全實作 ES6+ 的特性,我們能把這些新的語法特性套在自己的專案上嗎?透過 Babel 我們可以把 ES6+ 程式碼轉為等效的 ES5 程式碼,故我們可以在專案中使用 ES6+ 特性。Babel 是本系列另一本書 Modern JavaScript Tools and Skill 的重點之一,故本書不重覆篇幅。

    Chapter 1: New Keywords let and const

    在 ES5 以前,JavaScript 用 var 宣告變數,但 var 有一些不良的特性:

    • 可視域 (scoping)
    • 重覆宣告不會引發錯誤
    • 無法做為實質上的常數

    為了改善這些不良特性,故引入 letconst。除了相容於舊瀏覽器外,應優先使用 letconst

    Chapter 2: Using Map, Set, WeakMap, WeakSet

    在 ES5 以前,JavaScript 用物件實字 {} 做為映射 (map) 或集合 (set),但這樣做有一些顯著的缺點:

    • 鍵 (key) 一定要是字串
    • 無法有效地迭代
    • 和內建方法 (method) 相衝突

    在 ES6 後引入 MapSet 兩種新的物件,用來改善物件實字的缺點。至於 WeakMapWeakSet 則是在可能出現循環引用的情境中替代 MapSet 的物件,用法上幾無差異。

    Chapter 3: New Arrap.* and Array.prototype.* Methods

    本章簡短地介紹 ES6 中對 Array 物件增強的特性:

    • Array.from()
    • Array.prototype.find()
    • Array.prototype.findIndex()
    • Array.prototype.keys()
    • Array.prototype.values()
    • Array.prototype.fill()

    Array 本質上沒有改變,只是多些方法 (method),大略看一下即可。

    Chapter 4: New String Methods - String.prototype.*

    承續上一章的精神,本章簡短地介紹 ES6 中對 String 物件增強的特性:

    • String.prototype.startsWith()
    • String.prototype.endsWith()
    • String.prototype.includes()
    • String.prototype.repeat()
    • String.raw()

    由於 String 沒有什麼大幅變動,只是新增一些方法,簡單看一下即可。

    Chapter 5: New Number Methods

    承續前面章節的精神,本章簡短地介紹 ES6 中對 Number 物件增強的特性:

    • Number.isInteger()
    • Number.isNan()
    • Number.isFinite()
    • Number.isSafeInteger()

    由此可知,ES6 加入一些 Number 可用的判斷方法,對撰寫程式帶來一些便利性。

    Chapter 6: ES6 Arrow Functions: Fat and Concise Syntax in JavaScript

    Arrow 函式 (arrow function) 是一個新的語法,主要用於撰寫函式表達式 (function expression)。例如以下函式:

    $(document).ready(function () {
        // Implement your code here.
    });
    

    用純 JavaScript 搭上 arrow 函式改寫如下:

    document.addEventListener('DOMContentLoaded', () => {
        // Implement your code here.
    }, false);
    

    Arrow 函式的用意在讓 JavaScript 的語法更簡潔,但兩者有一些些差異:

    • this 的作用方式相異
    • Arrow 函式不能做為建構子 (constructor)
    • Arrow 函式不能做為生成器 (generator)
    • Arrow 函式沒有 arguments 物件

    由於 arrow 函式的用意是讓程式碼簡化,不是必備的功能,讀者可自行決定是否要在專案中使用這項特性。

    Chpater 7: Symbols and Their Use

    Symbol 是 ES6 引入的新特性,主要是做為獨一無二的 (unique) 符號,但其值不重要。如下例:

    let EAST = Symbol(),
        WEST = Symbol(),
        NORTH = Symbol(),
        SOUTH = Symbol();
    

    在 ES5 以前,我們會直接塞入字串或其他值,但那樣做無法表達該變數獨一無二的性質,Symbol 物件的出現,就是為了解決這個議題。本章介紹數個 Symbol 的使用情境,有興趣的讀者可以讀一讀。

    Chapter 8: How to Use Proxies

    Proxy 是 ES6 的新特性,目的是在 JavaScript 中寫元程式 (meta-programming)。透過 proxy,程式人可以透過程式去修改物件的行為。由於元程式是相對抽象的概念,本章有一些範例,可透過範例來了解如何使用 proxy。

    Proxy 包括三個要件:

    • Target:Proxy 要修改的物件
    • Handler:實作 proxy 的行為的物件,通常是物件實字
    • Traps:在 handler 中定義的函式,用來修改 target 的行為。

    以下範例摘自 MDN:

    var handler = {
        get: function(obj, prop) {
            return prop in obj ?
                obj[prop] :
                37;
        }
    };
    
    var p = new Proxy({}, handler);
    p.a = 1;
    p.b = undefined;
    
    console.log(p.a, p.b); // 1, undefined
    console.log('c' in p, p.c); // false, 37
    

    在本例中,我們修改 get 函式,當屬性不存時,回傳 37

    當然,proxy 算是相對困難的技巧,本章提供更多的說明和範例,有興趣的讀者可以讀一讀。由於 proxy 算是進階的特性,無法用 polyfill 來補,也無法用 Babel 來轉,如果專案要支援 Internet Explorer (IE),就應該避開 proxy。

    Chapter 9: Destructing Assignment

    解構指派 (destructing assignment) 算是一種指派運算的語法糖,透過這項特性可以簡化程式碼。像是以下的陣列:

    let [a, b, c] = [3, 4, 5];
    

    或是以下的物件實字:

    let {one: a, two: b, three: c} = {one: "eins", two: "zwei", three: "drei"};
    

    由於指派算是一個較小的特性,本章的重點放在各種透過解構簡化程式的情境,可以讀一讀,學習這些小技巧。

    Chapter 10: ES6 Generators and Iterators: a Developer’s Guide

    迭代器 (iterators) 和生成器 (generators) 是相當實用的特性。迭代器的使用方式如下:

    for (const element of collection) {
        // Do something here.
    }
    

    在 ES6 之後,我們可以不用索引來迭代容器,可以直接走訪容器。

    生成器是用來產生迭代器的函式,例如下列用來生成費伯那西數的生成器:

    function* getNextFib() {
        let a = 0;
        let b = 1;
        let c;
        
        while (true) {
            yield a;
            c = a + b;
            a = b;
            b = c;
        }
    }
    
    const fib = getNextFib();
    
    for (let i = 0; i < 10; i++) {
        console.log(fib.next().value);
    }
    

    本章對迭代器和生成器有較詳細的說明,有興趣的讀者可以讀一下。

    Chapter 11: Object-Oriented JavaScript: A Deep Dive into ES6 Classes

    class 算是 ES6 裡主要的新增特性之一。JavaScript 的物件是以原型 (prototype) 為基礎,引入 class 並不代表物件系統有所改變,而是用更好的語法來實作物件。在 ES6 之後,就不建議用舊有的建構函式那套手法來建立物件,除非是要維護舊專案。本章介紹數個 class 相關的議題:

    • 新式建構子 (constructor)
    • 建立私有屬性的手法
    • 靜態屬性和方法
    • 繼承 (單一繼承)
    • 達成多重繼承的手法

    這章算是值得一讀的章節。

    Chapter 12: Understand ES6 Modules

    模組算是 ES6 引入的新特性,原本的 JavaScript 的模組如下:

    • 網頁前端
    • 網頁後端
      • CommonJS
      • 用 bundler 將 JavaScript 程式碼打包成單一命令稿,像是 webpack
    • 網頁前後端通用

    前述所提的都是在 ES6 模組出現前的一些 JavaScript 的模組機制。本章介紹如何在專案中加入模組。

    雖然 ES6 模組立意良好,但模組會造成專案架構的改變,且有一定比例的瀏覽器不支援模組 (參考這裡),勢必要寫退路 (fallback)。甚至本書作者也建議在現階段的專案中,不一定要急著加入模組,等過一陣子模組更普遍再使用也不遲。

    Chapter 13: An Overview of JavaScript Promises

    Promises 是 ES6 裡重要的新特性,由於 JavaScript 程式以非同步模式來運行,有時會寫出複雜、難維護的回呼 (callback) 程式;透過 promises 可使得程式碼更簡潔易讀,一些常見的情境就是包裝 AJAX 程式,jQuery 新版本中也加入以 promise 為基礎的 API 呼叫,如下例:

    var jqxhr = $.post( "example.php", function() {
      alert( "success" );
    })
      .done(function() {
        alert( "second success" );
      })
      .fail(function() {
        alert( "error" );
      })
      .always(function() {
        alert( "finished" );
      });
    

    本章中有更多 promise 的寫法,有興趣的讀者可以讀一讀。Promise 讓程式碼更易寫易讀,是值得學習的新特性。

    Chapter 14: JavaScript Decorators: What They are and When to Use Them

    Decorator 在 Angular 和 TypeScript 中很流行,但在 JavaScript 中這項特性還沒穩定下來 (參考這裡),故筆者目前不建議使用這樣特性。有興趣的讀者可以自行閱讀。

    Chapter 15: Enhanced Object Literals

    本章介紹一些在 ES6 以後對於物件實字 {} 的增強:

    • 直接從變數初始化物件
    • 從物件實字建立函式的語法糖
    • 動態屬性 (dynamic property)
    • 物件解構 (object destructing)
    • Rest/spread 屬性

    這章有些內容和其他章節有一些重覆,可能有些內容很難歸類所造成。

    Chapter 16: Introduction to the Fetch API

    Fetch API 是新的抓取數據的 API,有點像先前的 XMLHttpRequest 物件,但加入一些新的功能,像是跨網域存取 (CORS) 及 HTTP origin 標頭等。本章介紹如何以 fetch API 搭配 promise 或 async/await,另外介紹 fetch API 發生錯誤的處理方式。

    雖然部分瀏覽器不支援 fetch API 但有 polyfill 可用,除了要支援較舊的瀏覽器外,應該可以放心使用此 API。

    Chapter 17: ES6 (ES2015) and Beyond: Understand JavaScript Versioning

    本章較偏歷史面及政策面,技術含金量相對低。一開始講到 JavaScript 的由來及標準化的過程,之後介紹一個語言的提案 (proposal) 制定的過程。本章的重點是看懂 JavaScript 的版本號:

    (補充表格)

    • N/A、ECMAScript 1、N/A
    • N/A、ECMAScript 2、N/A
    • N/A、ECMAScript 3、N/A
    • N/A、ECMAScript 5、ES5
    • ES2015、ECMAScript 2015、ES6
    • ES2016、ECMAScript 2016、ES7
    • ES2017、ECMAScript 2017、ES8
    • ES2018、ECMAScript 2018、ES9

    註:ECMAScript 4 遭廢棄而未發布。

    我們在談現代 JavaScript 是指 ES6 之後所新增的語法特性;相對來說,ES5 會當成瀏覽器實作的最低版本,也是 Babel 轉換的目標版本。

    Chapter 18: What’s New in ES2017: Async Functions, Improved Objects, and More

    本章簡短地介紹 ES2017 帶來的新特性:

    • asyncawait
    • Object 的新方法 (methos),包括 Object.values()Object.entries()Object.getOwnPropertyDescriptors()
    • 字串的新方法,包括 padStart()padEnd()

    ES2017 最重要改變的是 async 語法,可以讓非同步程式寫起來更簡潔,其他的部分簡單看一下即可。

    Chapter 19: What’s New in ES2018

    承續上一章,本章簡短地介紹 ES2018 的新特性:

    • 非同步迭代 (asynchronous iteration)
    • Promise.finally()
    • 用於物件解構 (object destructing) 的 rest/spread 語法
    • 一些對正規表示式的小幅強化

    由此可看出,ECMAScript 持續改善非同步程式的寫法。

    結語

    由本書的寫作方式可看出,本書比較適合已經會一些些 JavaScript 但想幫自己充電的程式人;對於程式新手或是完全不懂 JavaScript 的讀者來說,本書讀起來可能會過於吃力,而且無法理解為什麼 JavaScript 要引入這些新特性。

    本書的範例是典型的西方式寫法,沒有完整的範例而是短小的程式碼片段 (code snippets)。對於有經驗的程式人來說,這樣的書很容易抓到重點,但初學者可能覺得這樣的寫作方式過於困難。除了針對完全新手的書籍外,大部分書籍都會採用這種寫作方式,要慢慢習慣。

    本書承襲 SitePoint 系列書籍輕薄短小的特性,閱讀一次應該不會花太久的時間。但 JavaScript 有許多的議題,僅以 200 多頁的份量是無法完整交待的,所以 the Modern JavaScript Collection 這個系列以四本書的容量來介紹 JavaScript,讀者可視自己的需求單獨購買或成套購買。

    如何購買

    如果讀者想購買本書,可以參考以下的連結。讀者可依自己需求選擇要單買或是整套買。

    【分享本文】
    Facebook Twitter LinkedIn LINE Skype EverNote GMail Yahoo Email
    【贊助商連結】
    標籤: JAVASCRIPT
    【贊助商連結】
    【分類瀏覽】