JavaScriptES6Destructuring前端開發2026

JavaScript 解構賦值:從醜陋冗長到簡潔優雅

JavaScript 解構賦值完整教學!陣列解構、物件解構、預設值、巢狀解構攻略。2026 年工程師必看的 JS 語法指南!

· 5 分鐘閱讀

如果你從 CSS 或 HTML 背景剛進入 JavaScript,剛看到 const { name, age } = person 這樣的程式碼時,可能會想「這在搞什麼」。但當你學會解構賦值(destructuring)之後,你會發現過去那些「先宣告變數、再一個一個賦值」的四行程式碼,其實可以一行就完成。解構不是奇怪的語法糖——它是 JavaScript 裡,你一旦學會就再也回不去的語法。


什麼是解構賦值

解構賦值允許你從陣列物件中提取值,一次性建立多個變數:

// 過去的方式:四行程式碼
const person = { name: '小明', age: 28, city: '台北' };
const name = person.name;
const age = person.age;
const city = person.city;

// 現代的方式:一行程式碼
const { name, age, city } = person;

同樣的邏輯也適用於陣列:

const colors = ['red', 'green', 'blue'];

// 過去的方式
const first = colors[0];
const second = colors[1];

// 現代的方式
const [first, second] = colors;
console.log(first); // 'red'
console.log(second); // 'green'

從 ESLint 警告學解構

ESLint 是 JavaScript 開發者的好朋友——它會在你寫出不那麼乾淨的程式碼時發出警告。很多時候,這些警告都在暗示你「該用解構了」。

常見警告:重複賦值同一物件的多個屬性

// ESLint 可能會警告:
// "Expected destructuring for 'person.name'"

// 醜陋的寫法
const user = getUser();
const name = user.name;
const email = user.email;
const avatar = user.avatar;
const score = user.score;

// 簡潔的寫法
const { name, email, avatar, score } = getUser();

常見警告:參數物件未解構

// 函式接收一個物件作為參數
// 但沒有解構

// 醜陋的寫法
function createUser(user) {
  const name = user.name;
  const email = user.email;
  const role = user.role || 'user';
  // ...
}

// 簡潔的寫法
function createUser({ name, email, role = 'user' }) {
  // 參數直接解構,需要的值直接拿出來
  // ...
}

這個「在參數中解構」的語法,剛開始可能不適應,但它非常強大——當你呼叫函式時,只要傳入一個物件就可以了:

// 呼叫時可以只提供部分屬性
const user = createUser({
  name: '小明',
  email: 'xiaoming@example.com',
  // role 會使用預設值 'user'
});

物件解構:基礎

const book = {
  title: '原子習慣',
  author: 'James Clear',
  year: 2018,
  pages: 320,
};

// 基本語法
const { title, author } = book;
console.log(title);  // '原子習慣'
console.log(author); // 'James Clear'

// 重新命名
const { title: bookTitle, author: writer } = book;
console.log(bookTitle); // '原子習慣'
console.log(writer);   // 'James Clear'

// 預設值
const { title, price = 350 } = book;
console.log(price); // 350(因為 book 中沒有 price)

實用場景:從函式返回物件

// 函式返回一個物件
function getBrowserInfo() {
  return {
    name: 'Chrome',
    version: 130,
    platform: 'macOS',
  };
}

// 使用解構提取需要的值
const { name, version } = getBrowserInfo();
console.log(`${name} ${version}`); // 'Chrome 130'

陣列解構:基礎

const rgb = [255, 128, 0];

// 基本語法
const [red, green, blue] = rgb;
console.log(red);   // 255
console.log(green); // 128
console.log(blue);  // 0

// 跳過某些元素
const [first, , third] = rgb;
console.log(first);  // 255
console.log(third);  // 0

// 其餘元素
const [head, ...rest] = rgb;
console.log(head);  // 255
console.log(rest);  // [128, 0]

// 交換變數(不需要暫存變數)
let a = 1;
let b = 2;
[a, b] = [b, a];
console.log(a); // 2
console.log(b); // 1

實用場景:React Hooks

// React 的 useState 返回一個陣列
const [count, setCount] = useState(0);
const [user, setUser] = useState(null);
const [loading, setLoading] = useState(true);

// useEffect 返回的 cleanup 函式很少用到,可以用 _ 忽略
const [count, setCount, _] = useState(0);

巢狀解構:處理複雜資料

const company = {
  name: 'FrontEnd Corp',
  address: {
    city: '台北',
    district: '信義區',
    zip: '110',
  },
  employees: ['小明', '大華', '小美'],
};

// 巢狀物件解構
const {
  name,
  address: { city, district },
} = company;
console.log(city);    // '台北'
console.log(district); // '信義區'

// 巢狀陣列解構
const {
  employees: [firstEmployee, secondEmployee],
} = company;
console.log(firstEmployee);  // '小明'
console.log(secondEmployee); // '大華'

實用場景:API 回應

// 假設 API 返回這樣的資料
const apiResponse = {
  status: 'success',
  data: {
    user: {
      id: 123,
      profile: {
        name: '小明',
        avatar: 'https://example.com/avatar.jpg',
      },
    },
  },
};

// 用巢狀解構提取需要的数据
const {
  status,
  data: {
    user: {
      profile: { name, avatar },
    },
  },
} = apiResponse;

console.log(status); // 'success'
console.log(name);  // '小明'
console.log(avatar); // 'https://example.com/avatar.jpg'

綁定模式 vs 指派模式

綁定模式(Declaration)

// 使用 const 或 let 宣告新的變數
const { name, age } = person;   // const 宣告
let { x, y } = point;           // let 宣告

指派模式(Assignment)

// 已經存在的變數被賦予新值
let name, age;
({ name, age } = person);  // 需要用圓括號包裹
// 因為 {} 在 JavaScript 中預設是程式碼區塊

這個語法細節很重要——如果你在 if 或其他區塊外直接寫 { name, age } = person,JavaScript 會把前面的 {} 當作區塊而不是解構。


解構的實際重構案例

重構前:冗長的 API 處理

// 重構前
function handleApiResponse(response) {
  const data = response.data;
  const user = data.user;
  const userName = user.name;
  const userEmail = user.email;
  const userAvatar = user.avatar;
  const meta = data.meta;
  const totalPages = meta.totalPages;
  const currentPage = meta.currentPage;

  console.log(`${userName} (${userEmail})`);
  console.log(`Page ${currentPage} of ${totalPages}`);

  return {
    userName,
    userEmail,
    userAvatar,
    totalPages,
    currentPage,
  };
}

重構後:使用解構

// 重構後
function handleApiResponse({ data: { user: { name, email, avatar }, meta: { totalPages, currentPage } } }) {
  console.log(`${name} (${email})`);
  console.log(`Page ${currentPage} of ${totalPages}`);

  return { name, email, avatar, totalPages, currentPage };
}

一行參數搞定——所有需要的值直接從龐大的回應物件中被解構出來。


與其配套的語法:展開運算子

解構經常與展開運算子(spread operator)一起使用:

const { name, ...rest } = person;
console.log(name);  // '小明'
console.log(rest);  // { age: 28, city: '台北', ...其他屬性 }

// 合併物件
const defaults = { theme: 'light', language: 'zh-TW' };
const userPrefs = { theme: 'dark' };
const merged = { ...defaults, ...userPrefs };
// { theme: 'dark', language: 'zh-TW' }

結語:從「看起來很奇怪」到「無法回頭」

解構賦值是那種「剛開始覺得怪,學會之後停不下來」的語法。一旦你開始用 const { name, email } = user 取代 const name = user.name; const email = user.email;,你就會開始到處想用解構。

實用的建議:

  • 函式參數:盡可能解構,你可以一眼看出函式需要什麼值
  • API 回應:用巢狀解構提取你需要的一小部分
  • React Hooks:直接從返回的陣列解構,你一直在用這個模式

你不需要記住所有的語法——在實際寫的時候,ESLint 和 TypeScript 會提醒你「這裡可以用解構」。那個警告,其實是個很好的提示。


延伸閱讀

本文是「2026 JavaScript 實用語法」系列文章之一。