2022/02/21

ES6 語法 note

JavaScript ES6 的一些新的語法的筆記

var, let, const

  • var 的作用域為 function。
  • let 與 const 作用域為 block,也就是 大括號 { } 裡面
  • const 宣告的變數無法被 re-assigned

Arrow Function

// 傳統 function 寫法
var call = function(someone) {
  return someone + ' is called';
}

var plus = function(A, B) {
  return A + B;
}

// arrow function
var call = someone => someone + ' is called';

var plus = (A, B) => A + B;

arrow function 的 this 是外面的 this,跟原本 function 的 this 不同

展開符號 ...

展開運算子 (Spread Operator) / 其餘運算子 (Rest Operator)

合併數個陣列

let groupA = ['小明', '杰倫', '阿姨'];
let groupB = ['老媽', '老爸'];
let groupAll = [...groupA, ...groupB];
console.log(groupAll);
// ['小明', '杰倫', '阿姨','老媽', '老爸']

複製陣列(淺複製)

用展開符號來複製 A 陣列,則會是 call-by-value 的複製,修改 B 不會影響到 A。

如果直接 let groupB = groupA 會是 call-by-reference

let groupA = ['小明', '杰倫', '阿姨'];
let groupB = [...groupA] // 新陣列
groupB.push('阿明');
console.log(groupA); // 不會有阿明

類陣列

querySelectorAll() 取出來的 NodeList 會以類陣列的形式呈現所有被選取的節點,但它卻不是真正的陣列。透過展開符號可以複製類陣列中的內容,藉此將類陣列轉為真正的陣列。

let doms = document.querySelectorAll('li'); // doms 為類陣列
let newDoms = [...doms]; // newDoms 為陣列

函式內建的 arguments 物件也是類陣列,arguments 會包含所有傳入函式的參數。

其餘參數

如果不確定要傳入函式的參數數量,可以在函式的最後一個參數前面加上展開符號(該參數就會變成其餘參數),就能把多傳入的參數值以陣列的形式,容納在其餘參數中。注意,函式裡只能有一個其餘參數,而且一定要放在最右邊。

function moreMoney(name, ...money) {
  console.log(name, money);
  // "Grace" [100, 200, 300, 400, 500]
}
moreMoney('Grace', 100, 200, 300, 400, 500);

ES Module 與 import 、 export

可將每個 JS 檔案當作一個獨立模組,A.js 匯出 export,在 B.js 匯入 import

// A.js
export const aString = "A String";

export function aFunction() {
    console.log("aFunction");
}

export const aObject = {a:1};


// B.js
import {aString, aFunction, aObject} from './A.js';

console.log(aString);
console.log(aObject);
aFunction();


// test.html
<!DOCTYPE html>
<html lang="en">

<head>
</head>

<body>
  <script type="module" src="./A.js"></script>
  <script type="module" src="./B.js"></script>

</body>
</html>

String Template

以往要在

  • 裡面加上圖片

    // HTML
    <ul class="list">
      <li>
        <img src="logo.png">
      </li>
    </ul>
    // JS
    // 用 const 選取 DOM
    const list = document.querySelector('.list')
    // 用 const 儲存要放入的圖片路徑
    const imgURL = 'logo.png';
    
    // 舊的寫法,要用字串連接
    list.innerHTML = '<li><img src='+ imgURL +'></li>'
    
    // 新的寫法,可用 `` 裡面放入 ${變數}
    list.innetHTML = `<li><img src=" ${imgURL} "></li>`

    可搭配陣列輸出

    • // 陣列
      const people = [
        {
          name: '小明',
          friends: 2
        },
        {
          name: '阿姨',
          friends: 999
        },
        {
          name: '杰倫',
          friends: 0
        }
      ]
      
      let newUl = `
        <ul> ${people.map(person =>
          `<li>我叫做 ${person.name}</li>`)
          .join('')}
        </ul>`

      Destructing Assignment

      將陣列或物件的資料直接拆開對應賦值

      const user = {
          id: 42,
          name: 'juice',
          fullname: {
              first: 'orange',
              last: 'juice'
          }
      };
      
      
      const {id, name, fullname} =  user;
      
      console.log(id);
      console.log(name);
      console.log(fullname);
      const num = [1,2,3,4,5];
      
      const [x,y] = num;
      
      //1
      console.log(x);
      //2
      console.log(y);

      常用陣列function

      forEach()

      ​ 對每一個元素運算一次 fuction

      map()

      ​ 運算後,回傳新的陣列

      reduce()

      find()

      ​ 只回傳第一個符合條件的元素

      filter()

      ​ 回傳符合條件的元素的新陣列

      every()

      ​ 所有元素都符合條件才回傳 true

      some()

      ​ 有部分元素符合條件就回傳 true

      Promise

      為解決非同步的問題,提供 Promise 物件

      成功時要呼叫 resolve,失敗時呼叫 reject。

      用 then 綁定 fullfilled 或 rejected 時,分別要執行的 function

      // 宣告 promise 建構式
      let newPromise = new Promise((resolve, reject) => {
        // 傳入 resolve 與 reject,表示資料成功與失敗
        let ran = parseInt(Math.random() * 2); // 隨機成功或失敗
        console.log('Promise 開始')
        if (ran) {
          setTimeout(function(){
            // 3 秒時間後,透過 resolve 來表示完成
            resolve('3 秒時間(fulfilled)');
          }, 3000);
        } else {
          // 回傳失敗
          reject('失敗中的失敗(rejected)')
        }
      
      });
      
      newPromise.then((data)=> {
        // 成功訊息 (需要 3 秒)
        console.log(data);
      }).catch((err)=> {
        // 失敗訊息 (立即)
        console.log(err)
      });

      async, await

      let runPromise = (someone, timer, success = true) => {
        console.log(`${someone} 開跑`);
        return new Promise((resolve, reject) => {
          // 傳入 resolve 與 reject,表示資料成功與失敗
          if (success) {
            setTimeout(function () {
              // 3 秒時間後,透過 resolve 來表示完成
              resolve(`${someone} 跑 ${timer / 1000} 秒時間(fulfilled)`);
            }, timer);
          } else {
            // 回傳失敗
            reject(`${someone} 跌倒失敗(rejected)`)
          }
        });
      }
      
      // 此段函式並不會影響其它函示的執行
      runPromise('小明', 3000).then(someone => {
        console.log('小明', someone)
      });
      // 以下這段 console 會在 promise 結束前就執行
      console.log('這裡執行了一段 console');

      await 會等待 promise 的處理結果

      // 此段函示會中斷其它函式的運行
      let mingRun = await runPromise('小明', 2000)
      console.log('跑完了:', mingRun);
      let auntieRun = await runPromise('漂亮阿姨', 2500);
      console.log('跑完了:', auntieRun);

      async 類似 promise,但會將 await 包裝在裡面

      const asyncRun = async () => {
        let mingRun = await runPromise('小明', 2000);
        let auntieRun = await runPromise('漂亮阿姨', 2500);
        return `${mingRun}, ${auntieRun}`
      }
      asyncRun().then(string => {
        console.log(string)
      }).catch(response => {
        console.log(string)
      })

      References

      [JS] JavaScript ES6 常用語法筆記

      JavaScript Await 與 Async

沒有留言:

張貼留言