JavaScript – ES7 – ES12 新特性

ES 7 新特性

Array.prototype.includes

JavaScript
// Array.prototype.includes
const arr = [1];

// 與 indexOf 一樣
if (arr.indexOf(1) !== -1)
    console.log(`A: 存在 1`);

if (arr.includes(1))
    console.log(`B: 存在 1`);
    
// 也可以替代多個判斷
let test = 'a';
if (test === 'a' || test === 'b' || test == 'c')
    console.log(`A: 存在a或b或c`);

if (['a', 'b', 'c'].includes(test))
    console.log(`B: 存在a或b或c`);

指數運算符 **

JavaScript
  // 相等於 Math.pow
  console.log("A", Math.pow(2, 10));
  console.log("B", 2 ** 10);

ES 8 新特性

字符串填充 String.padStart 及 String.padEnd

JavaScript
/**
 * 字符串填充目的是令字串添加字符達到指定長度
 * padStart 是在字串前面添加,padEnd 是在字串後面添加
 */

// String.padStart(targetLength, [padString])
console.log("A", '0.0'.padStart(4, '10'));
console.log("B", '0.0'.padStart(20));
console.log("C", '0.0'.padStart(15, 'cdef'));

// String.padEnd(targetLength, [padString])
console.log("D", '0.0'.padEnd(4, '0'));
console.log("E", '0.0'.padEnd(20));
console.log("F", '0.0'.padEnd(15, "cdef"));
運行結果

Object.values()

JavaScript
/**
 * Object.values()
 * 返回一個包含所有對象自身屬性值的數組
 */

const person = { name: 'Peter', age: 20};
console.log(Object.values(person));
const people = ['Peter', 'David'];
console.log(Object.values(people));

Object.entries()

JavaScript
/**
 * Object.entries()
 * 返回一個包含所有對象自身屬性的數組,作為 [key,value]
 */

const person2 = { name: 'David', age: 30};
console.log(Object.entries(person2));
const people2 = ['David', 'Peter'];
console.log(Object.entries(people2));

for(let [key,value] of Object.entries(person2)){
  console.log(`${key}: ${value}`);
}

async / await

JavaScript
/**
 * async / await
 * 利用async函數將異步操作包起來
 * 在函數內部使用await 命令等待異步操作完成
 **/
const readFile = function(fileName){
    return new Promise(function (resolve, reject){
        // read file logic
        if(error) return reject(error);

        resolve(data);
    });
}

const asyncReadFile = async function(){
    const file1 = await readFile('filePath1');
    const file2 = await readFile('filePath2');

    console.log(file1.toString());
    console.log(file2.toString());
}

ES 9 新特性

Promise.finally()

JavaScript
/**
 * Promise.finally()
 * 無論Promise 成功或失敗,也是運行裡面的代碼
 */

 // IOS真機環境下Promise 對象不存在finally方法
if(!Promise.prototype.finally){
    Promise.prototype.finally = function(cb){
        return this.then((res) => {
            cb && cb(res);
        }, (error) => {
            cb && cb(error);
        });
    };
}

Object Rest / Spread

JavaScript
/**
 * Object Rest / Spread
 * 三個點 (...) 用於 Array
 * Rest 參數可以允許將不一定數量的參數提取為1個Array
*/

send(1,2,3,4,5,6);

function send(p1, p2, ...p3){
    // p1 = 1
    // p2 = 2
    // p3 = [3, 4, 5, 6]
}

// ...p3 即提取剩餘參數,並以Array來儲存

const values = [99, 100, -1, 48, 16];

console.log(Math.max(...values)); // 100

// 可以給函數傳送參數

send({
    a: 1,
    b: 2,
    c: 3
});

function send({a, ...x}){
    // a = 1
    // x = { b: 2, c: 3 }
}

// 可以用作Object 複製
const obj1 = { a: 1, b: 2, c: 3};
const obj2 = { ...obj1, z: 26};
// obj2 會是 { a: 1, b: 2, c: 3, z: 26}

正則表達式命名

JavaScript
/**
 * 正則表達式命名 
 * 可以使用符號 "?",在"?"後立即命名
*/

// 原正則寫法: /([0-9]{4})-([0-9]{2})-([0-9]{2})/
// 利用正則表達式命名

const newDate = /(?<year>[0-9]{4})-(?<month>[0-9]{2})-(?<day>[0-9]{2})/;
const match = newDate.exec('2020-04-30');
const year = match.groups.year; // 2020
const month = match.groups.month; // 04
const day = match.groups.day; // 30

// 也可以使用在 replace()中,將日期轉換成其他格式
const testDate = '2018-04-30';
const updatedDate = testDate.replace(newDate, '$<month>-$<day>-$<year>'); // 04-30-2018

異步迭代

JavaScript
/**
 * 異步迭代
 * 可以利用此特性輕鬆創建異步代碼循環
 * 
*/

const fn = (time) => {
    return new Promise((resolve, reject){
        setTimeout(() => {
            resolve(`${time}s 後,執行成功了`);
        }, time);
    });
};
let arr = [fn(3000), fn(2000), fn(1000)];
async function fn2(){
    for await(e of arr){
        console.log(e);
    }
}

fn2();
// 輸出如下
// 3000s 後,執行成功了
// 2000s 後,執行成功了
// 1000s 後,執行成功了

ES 10 新特性

String.trimStart() 及 String.trimEnd()

JavaScript
/**
 * String.trimStart() 及 trim.End()
 * 清除字串首或尾空白字符
*/

console.log("   aaa".trimStart()); // aaa
console.log("bbb   ".trimEnd()); // bbb

Object.fromEntries()

JavaScript
/**
 * Object.fromEntries()
 * 返回一個給定對象自身可枚舉屬性的鍵值Array
 * Object.fromEntries() 是 Object.entries() 的反轉
 * Object.fromEntries() 可以將 map或Array 轉成 Object
 */

 const arr = [ ['0', 'a'], ['1', 'b'], ['2', 'c']] ;
 const obj = Object.fromEntries(arr); // { 0: "a", 1: "b", 2: "c" }

Array.flat() 及 Array.flatMap()

JavaScript
 /**
  * Array.flat() 及 Array.flatMap()
  * flat() 用於 Array 降維,還可以去除Array 的 null
  * flatMap() 相當於 map()的基礎上將結果壓平1層
  */

 // flat() 降維
 const arr3 = [1, 2, [3, 4, [5, 6]]];
 arr3.flat(2); // 壓平2層
 // [1, 2, 3, 4, 5, 6]

 // flat() 去除 null
 const arr4 = [1, 2, , 4, 5];
 arr4.flat();
 // [1, 2, 4, 5]

 // flatMap() 壓平1層
 const arr1 = [1, 2, 3, 4];
 arr1.map(x => [x * 2]); // [[2], [4], [6], [8]]
 arr1.flatMap(x => [x * 2]); //[2, 4, 6, 8]

 // flatMap() 只能壓平一層
 arr1.flatMap(x => [[x * 2]]); // [[2], [4], [6], [8]]

修改 catch 綁定

JavaScript
 /**
* 修改 catch 綁定
*/

 // 以前的寫法
 try{} catch(e) {}
 // 現在的寫法
 try{} catch{}

ES 11 新特性

Optional Chaining

JavaScript
/**
 * Optional Chaining
 * 用作判斷屬性是否存在,更簡潔的寫法
 */

// 過往的寫法
const street = user.info && user.info.address && user.info.address.street;
// 現在的寫法
const street = user.info?.address?.street;

Nullish coalescing Operator

JavaScript
/**
 * Nullish coalescing Operator
 * 空值合併運算符
 * 當左側為 null 或 undefined 時,返回右側的參數,否則返回左側的參數
 * 與 || 的分別是, || 是左側為false 的情況也會當作是
 */

const undefinedValue = response.settings.undefinedValue ?? 'some other default';

String.prototype.matchAll

JavaScript
/**
 * String.prototype.matchAll
 * matchAll() 返回一個包含所有匹配正則表達式及分組捕獲結果的迭代器,包括子項
 */

const regexp = /t(e)(st(\d?))/g;
const str = 'test1test2';
str.match(regexp); // match方法
// Array ['test1', 'test2']
let array = [...str.matchAll(regexp)]; // matchAll 返回的是一個迭代器,不能直接守為Array
array[0]; // ['test1', 'e', 'st1', '1', index: 0, input: 'test1test2', length: 4]
array[1]; // ['test2', 'e', 'st2', '2', index: 5, input: 'test1test2', length: 4]

Promise.allSettled

JavaScript
/**
 * Promise.allSettled
 * allSettled 統一處理 Promise的狀態
 * 當所有Promise 對象狀態都變為resolved 或 rejected時,返回一個狀態Array
 */

const promise1 = new Promise(function(resolve, reject){
    setTimeout(function(){
        reject("promise1");
    }, 2000);
});

const promise2 = new Promise(function(resolve, reject){
    setTimeout(function(){
        resolve("promise2");
    }, 3000);
});

const promise3 = Promise.resolve("promise3");
const promise4 = Promise.reject("promise4");

Promise.allSettled([promise1, promise2, promise3, promise4]).then((args) => {
    console.log(args);

    /*
        輸出如下
        result:
        [
            {"status": "rejected", "reason": "promise1"},
            {"status": "fulfilled", "reason": "promise2"},
            {"status": "fulfilled", "reason": "promise3"},
            {"status": "rejected", "reason": "promise4"},
        ]
    */
});

Class的private function 及 variable

JavaScript
/**
 *  Class 的private function 及 variable
 * 使用 # 可以在Class 中定義
 */

class Foo{
    #a;
    #b;

    constructor(a, b){
        this.#a = a;
        this.#b = b;
    }

    #sum(){
        return this.#a + this.#b;
    }

    printSum(){
        console.log(this.#sum());
    }
}

ES 12 新特性

String.replaceAll

JavaScript
/**
 * String.replaceAll
 * 替換所有匹配字符串
 */

const str = "Hello world, Hello Peter!";
const new_str = str.replaceAll("Hello", "Hi");
console.log(new_str); // Hi world, Hi Peter!

Logical Assignment Operators 邏輯賦值操作符

JavaScript
/**
 * Logical Assignment Operators 邏輯賦值操作符
 * 旨在不影響可讀性的情況下盡可能最小化代碼量
 */

a ||= b; // 等同於 a || ( a = b);
a &&= b; // 等同於 a && (a = b);
a ??= b; // 等同於 a ?? (a = b);

// 可用於緩存變量,減少耗時操作,提高性能,例如
return this.appShowScene ??= wx.getStorageSync('appShowScene');

// 等同於以下
if(this.appShowScene){
    return this.appShowScene;
}
this.appShowScene = wx.getStorageSync('appShowScene');
return this.appShowScene;

Promise.any()

JavaScript
/**
 * Promise.any
 * Promise.any() 有一個子實例成功就會當作成功
 * 當全部都失敗才會失敗
 */

Promise.any([promise1, promise2]).then(() => {})
// promise1 和 promise2 任意一個成功就會 then

Numeric separators 數字分隔符

JavaScript
/**
 * Numeric separators 數字分隔符
 * 數字分隔符不影響原本的數值,增加可讀性
 */
console.log(1_000_000_000); // 1000000000
console.log(10.000_001);    // 10.000001

開始在上面輸入您的搜索詞,然後按回車進行搜索。按ESC取消。

返回頂部