iT邦幫忙

2025 iThome 鐵人賽

DAY 7
0
Modern Web

JavaScript 進階修煉與一些 React ——離開初階工程師新手村的頭30天系列 第 7

離開 JS 初階工程師新手村的 Day 07|新武器庫:ES6+ 語法

  • 分享至 

  • xImage
  •  

昨天提到了 ES6 的 Class super 語法糖,今天來繼續看 ES6 還有什麼其他的語法。

解構賦值(Destructuring Assignment)

解構賦值可以從陣列或物件中快速提取值,並直接指派給變數。

範例

用在物件
https://ithelp.ithome.com.tw/upload/images/20250918/20168365qPW7yL3jkK.png

用在陣列
https://ithelp.ithome.com.tw/upload/images/20250918/201683657ojHRkAqXi.png

展開運算子(Spread & Rest Operator)

使用 ... 來展開陣列或物件,或收集剩餘的值。

範例

陣列展開

const arr1 = [1, 2];
const arr2 = [...arr1, 3, 4];  // [1, 2, 3, 4]

物件合併

const base = { a: 1, b: 2 };
const extended = { ...base, c: 3 }; // { a: 1, b: 2, c: 3 }

函式參數收集

function sum(...nums) {
  return nums.reduce((a, b) => a + b, 0);
}
sum(1, 2, 3); // 6

提升簡潔性與可維護性

  • 操作陣列/物件更直觀,取代 concat()Object.assign() 等繁瑣寫法
  • 搭配解構可靈活取值與收集其他屬性
const { a, ...rest } = { a: 1, b: 2, c: 3 };
// a = 1, rest = { b: 2, c: 3 }

這麼寫的好處,除了可以取代重複的 obj.property、減少程式碼,使得程式碼更簡潔。然而,在 React 中必須特別注意!因為 React 中的狀態都應該要是 immutable 的,才能使狀態改變時去 trigger 全面重新繪製。但是假設今天使用巢狀 array 或是巢狀物件,在做比較的時候,會對 reference 進行比較,因此即便裡頭的某些值發生改變,子層級的 reference 維持相同,即違反了 immutable 的原則。

https://ithelp.ithome.com.tw/upload/images/20250918/20168365D8MLS2Gzha.png

假設我們有這個狀態:

const [state, setState] = useState({
  app: {
    user: {
      profile: {
        settings: {
          notifications: {
            email: true,
            push: false,
            sms: true
          }
        }
      }
    }
  }
});

當我們想要把 push 改成 true 時,若使用展開式且需要同時尊循 immutable 的特性時,那我們就會寫出難以閱讀、難以維護的程式碼

setAppState({
  ...appState,
  user: {
    ...appState.user,
    profile: {
      ...appState.user.profile,
      personal: {
        ...appState.user.profile.personal,
        contact: {
          ...appState.user.profile.personal.contact,
          address: {
            ...appState.user.profile.personal.contact.address,
            city: 'Kaohsiung'
          }
        }
      }
    }
  }
});

Immer

  • 程式碼簡潔
  • 看起來像直接修改,但實際是 immutable
  • 自動處理深層拷貝

https://ithelp.ithome.com.tw/upload/images/20250918/20168365rASUyNUie1.png


模組化(ESM vs CommonJS)

模組化讓程式碼拆分成可重用的模組。ESM 是 ES6 的標準模組系統,而 CommonJS 是 Node.js 傳統使用的模組系統。

比較項 ESM (ES Modules) CommonJS
語法 import / export require / module.exports
載入 靜態載入(compile-time) 動態載入(runtime)
是否支援 tree-shaking

Tree Shaking 是個優化的方式,在JavaScript 中用來表示移除沒用的程式碼

範例

ESM

// math.js
export function add(a, b) { return a + b; }

// main.js
import { add } from './math.js';
console.log(add(2, 3)); // 5

CommonJS

// math.js
function add(a, b) { return a + b; }
module.exports = { add };

// main.js
const { add } = require('./math');
console.log(add(2, 3)); // 5

Proxy / Reflect

Proxy 可攔截物件的操作(如存取屬性、設值),讓你能自定義行為;Reflect 則是用來統一這些底層操作的方法。

範例

https://ithelp.ithome.com.tw/upload/images/20250918/201683653RERCSOEVj.png

Reflect 搭配 Proxy
https://ithelp.ithome.com.tw/upload/images/20250918/20168365c5LrP3yCFl.png

提升可維護性與可擴展性

  • 可實現資料驗證、偵錯日誌、Vue 等框架的響應式系統
  • Proxy + Reflect 讓攔截更一致、可預測
  • 提升封裝性,不需改變原始物件即可加上額外邏輯

Symbol

Symbol 是 ES6 引入的一種唯一值,常用於建立不會與其他屬性衝突的物件 key,適合做私有屬性、常數、meta programming。像是以下的範例, Symbol 規範住的屬性將不會被列舉。
https://ithelp.ithome.com.tw/upload/images/20250918/20168365FbpgTz3mp3.png


Iterator(可迭代協議)

讓物件可被 for...ofspread 使用,實作 [Symbol.iterator]() 方法即可。

範例

https://ithelp.ithome.com.tw/upload/images/20250918/20168365XwRVGoFZH3.png


Generator(生成器函式)

一種「可暫停執行」的函式。用 function* 宣告,搭配 yield 控制流程。

範例

https://ithelp.ithome.com.tw/upload/images/20250918/201683657OSPPdgVYE.png

Generator vs Iterator

  • Generator 可以自動實作 iterator
  • yield 讓你控制每次執行的位置與狀態

上一篇
離開 JS 初階工程師新手村的 Day 06|繼承之力:super() 的英雄召喚
下一篇
離開 JS 初階工程師新手村的 Day 08|從新手短劍到魔法武器:ES6+ 重構實戰
系列文
JavaScript 進階修煉與一些 React ——離開初階工程師新手村的頭30天10
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言