iT邦幫忙

第 12 屆 iT 邦幫忙鐵人賽

DAY 21
0
Modern Web

《你的地圖會說話? WebGIS與JavaScript的情感交織》系列 第 21

還在ES6?那你有聽過ES7、ES8嗎?

在撰寫JS的時候,常常會問:「這是ES5語法?還是ES6?IE有沒有支援?」
相信大家都有個疑問,ES6為ECMAScript2015,2015年出的語法竟然是最新的?!

已經過了五年了耶!那ES7、ES8呢?怎麼沒有人討論?
那是因為ES6是大幅度的更新,而ES7、ES8都只是小幅度增修,因此討論度較低。
其實我們平常在用的某些語法,可能已經是ES7、ES8了呢!

今天就讓我來簡單為大家介紹ES7、ES8新出的語法吧!
(偶也還在學習中,歡迎在留言區補充或是糾正呦!)


ECMAScript 歷史與進程

JavaScript的全名為ECMAScript,為1997年出的程式語言,更新了幾版之後,
2009年12月才出了大家熟知的ES5。那為何直到2015年才出ES6呢?時隔五年多。
在當時的時代背景,需要與DOM互動的腳本語言,
Java Applets、ActiveX、Flash百家爭鳴的時代,
Google在2013年宣佈淘汰Java,後來也淘汰了Flash,最終由JavaScript取得勝利。
2008年chrome發佈,並在2014年成為最多人使用的瀏覽器,
也讓大家逐漸重視Web的發展。

JavaScript程式語言的提案階段進程

  • 階段0: Strawperson 草擬
  • 階段1: Proposal 提議
  • 階段2: Draft 草案
  • 階段3: Candidate 表決
  • 階段4: Finished 定案

詳見此

↓ JavaScript的版本演進
https://ithelp.ithome.com.tw/upload/images/20201006/20130604nKlTyR58Fg.jpg
圖片來源: 維基百科

ECMAScript 7(2016)

  • Array.prototype.includes()

陣列新增了原型方法includes,簡化了尋找陣列中有無某元素的語法。

↓ 以前的寫法,透過indexOf是否不為-1,判斷陣列有無該值。

        let arr = ['John', 'Dennis', 'Perry', 'Tom'];
        if (arr.indexOf('Perry') !== -1) {
            console.log('Hi~ Perry');
        }

↓ ES7寫法

        if (arr.includes('Perry')) {  // ES7 Array.prototype.includes()
            console.log('Hi~ Perry');
        }

↓ 結果
https://ithelp.ithome.com.tw/upload/images/20201006/201306046zS4IQG0RT.jpg

  • Exponentiation Operator 指數運算子

透過指數運算子可以很方便的直接做指數的運算。

↓ 以往我們要撰寫指數,可以寫類似這樣子的迭代,如果不滿足條件,乘以傳入的數字後呼叫function本身

        let Exponent = (base, exponent) => {
            if (exponent === 1) {
                return base;
            } else {
                return base * Exponent(base, exponent - 1);
            }
        }
        console.log(Exponent(2, 10));  // 2的10次方

↓ 或者使用Math.pow去運算

        console.log(Math.pow(2, 10));

↓ ES7寫法

        console.log(2 ** 10);  // ES7  Exponentiation operator

↓ 結果
https://ithelp.ithome.com.tw/upload/images/20201006/20130604TOXtl0iC4f.jpg

ECMAScript 8(2017)

  • Async & Await

前面的篇章講述過request的非同步問題,詳見[5-2] Callback & Promise - 解決request非同步的四種解法。除了能夠利用callback function或回傳promise物件外,ES8新增了async與await搭配,讓語法上更加直觀。

↓ 假如我們fetch後直接取值

        function FetchData(url) {
            let request = fetch(url);
            let text = request.text();

            console.log(text);
        }
FetchData('https://api.nlsc.gov.tw/other/TownVillagePointQuery/120.698659/24.156250/4326');

因為fetch還沒獲得回傳,就先執行下一行,request為undefined,取值就會Error。

↓ Error
https://ithelp.ithome.com.tw/upload/images/20201006/20130604eEOuQ8jucO.jpg

↓ ES8 搭配async與await

        async function FetchData(url) {
            let request = await fetch(url);
            let text = await request.text();

            console.log(text);
        }
FetchData('https://api.nlsc.gov.tw/other/TownVillagePointQuery/120.698659/24.156250/4326');

async表示這個function有非同步呼叫,await則表示需要等候。

↓ 箭頭函式指派為變數可以寫成這樣

        const FetchData = async (url) => {
            let request = await fetch(url);
            let text = await request.text();

            console.log(text);
        };
FetchData('https://api.nlsc.gov.tw/other/TownVillagePointQuery/120.698659/24.156250/4326');

async一般接在function之前,如果function省略則接在parameter之前。

↓ 結果正常
https://ithelp.ithome.com.tw/upload/images/20201006/20130604knFpJpXgNT.jpg

  • Object.values

之前講解過Object.keys(),用以取得物件中所有資料的屬性名稱,並且為陣列;
再利用迴圈,把陣列中的所有內容秀出來。

↓ 新增一個物件做為範例

        const menu = {
            salad: '帝王蟹腳凱薩沙拉',
            appetizer: "松露鵝肝魚子醬",
            soup: "馬賽海鮮濃湯",
            meat: '日本A5和牛肋眼',
            dessert: '法式手工舒芙蕾佐千層派'
        }

↓ 利用Object.keys(menu)取得屬性名稱陣列,再用Array.prototype.map()重組陣列。

        const dinner = Object.keys(menu).map(key => menu[key]);
        console.log(dinner);

↓ ES8的寫法,直接用Object.values可以直接取得所有值的陣列。

        const dinner = Object.values(menu);
        console.log(dinner);

↓ 結果
https://ithelp.ithome.com.tw/upload/images/20201006/201306045kL5OpxPKw.jpg

  • Object.entries

Object.entries可以把物件的key與value都存取出來,成為二維陣列。
內層陣列中第一個元素為key,第二個為value。

↓ 用Object.entries把menu提取出來

        console.log(Object.entries(menu));

↓ 二維陣列
https://ithelp.ithome.com.tw/upload/images/20201006/2013060489hstLBbZ5.jpg

↓ 利用Object.keys(menu)取得欄位名稱,再迴圈通通秀出來!

        Object.keys(menu).forEach(key => {
            console.log(`${key} : ${menu[key]}`);
        });

↓ ES8 利用Object.entries把menu提取出來後,搭配let...of...顯示。

        for (let [key, value] of Object.entries(menu)) {
            console.log(`${key} : ${value}`)
        }
  • String.prototype.padStart & padEnd

String原型方法新增了向左補滿(padStart)及向右補滿(padEnd)的方法。
第一個參數為補到幾位數,第二個參數為用什麼字串來補。

↓ padStart

        const str = 'qq';
        console.log(str.padStart(7, 'a'));   // 用'a'向左補滿7位數
        console.log(str.padStart(7, 'ab'));  // 用'ab'向左補滿7位數
        console.log(str.padStart(1, 'ab'));  // 1 < str.length,讀取str本身

↓ 結果
https://ithelp.ithome.com.tw/upload/images/20201006/201306043ANeuafxbs.jpg

如果補到的位數小於字串本身長度,會直接讀取字串本身。

↓ padEnd

        console.log(str.padEnd(7, 'a'));   // 用'a'向右補滿7位數
        console.log(str.padEnd(7, 'ab'));  // 用'ab'向右補滿7位數
        console.log(str.padEnd(1, 'ab'));  // 1 < str.length,讀取str本身

↓ 結果
https://ithelp.ithome.com.tw/upload/images/20201006/20130604oKgv6hqKkm.jpg


除了ES7跟ES8以外,還有ES9一直到今年的ES11!
大家有興趣也可以去看看JS多了什麼變革!
不過有些也只是在階段0~3呢!

講了兩三天的JS語法,
明天要回歸WebGIS啦!

最近天氣越來越涼,入秋囉!/images/emoticon/emoticon10.gif


上一篇
[番外篇] 從npm安裝到活用Webpack Babel - 十分鐘就上手
下一篇
[8-1] 展點多到爆?那就試試看 Leaflet MarkerCluster吧!
系列文
《你的地圖會說話? WebGIS與JavaScript的情感交織》30

尚未有邦友留言

立即登入留言