본문으로 건너뛰기
기술스택 · stack/javascript/구조 분해: 배열과 객체에서 필요한 값만 꺼내기

JavaScript · 5장 자료구조와 자료형

구조 분해: 배열과 객체에서 필요한 값만 꺼내기

const name = user.name; const age = user.age;처럼 같은 이름을 두 번씩 쓰는 코드를 한 줄로 줄이는 문법이 구조 분해예요. 앞 글들에서 const [y, m, d] = …나 for (const [k, v] of …)로 조금씩 봤던 그 문법을, 실무에서 쓰는 모양별로 정리해요.

#5.9

01. 배열 구조 분해: 순서대로 꺼내기

대괄호를 등호 왼쪽에 쓰면 배열을 만드는 게 아니라 배열에서 순서대로 꺼내 변수에 담아요. 필요 없는 자리는 쉼표로 건너뛰고, 남은 것을 통째로 받으려면 ...이름을 마지막에 써요.

const [first, second] = ['연필', '공책', '지우개'];
console.log(first, second);          // 연필 공책

const [, , third] = ['연필', '공책', '지우개'];
console.log(third);                  // 지우개 — 앞 두 자리는 건너뛰었어요

const [head, ...rest] = [1, 2, 3, 4];
console.log(head, rest);             // 1 [2, 3, 4]

const [year, month, day] = '2026-11-07'.split('-');
console.log(year, month, day);       // 2026 11 07

let a = 1, b = 2;
[a, b] = [b, a];                     // 임시 변수 없이 두 값 바꾸기
console.log(a, b);                   // 2 1

배열 구조 분해는 순서가 의미를 가지는 값에 잘 맞아요. split 결과, Object.entries의 [키, 값] 짝(entries), 그리고 React의 const [count, setCount] = useState(0)처럼 두 값을 짝으로 돌려주는 함수예요.

02. 객체 구조 분해: 이름으로 꺼내기

중괄호를 왼쪽에 쓰면 객체에서 같은 이름의 속성을 꺼내요. 순서는 상관없어요. 다른 변수 이름으로 받고 싶으면 속성: 새이름, 값이 없을 때 쓸 기본값은 = 기본값으로 적어요.

const user = { name: '하늘', age: 27, city: '서울' };

const { name, age } = user;
console.log(name, age);                    // 하늘 27

const { name: userName, role = 'guest' } = user;
console.log(userName, role);               // 하늘 guest — role이 없어서 기본값

const { nickname = '익명' } = { nickname: null };
console.log(nickname);                     // null — 기본값은 undefined일 때만 써요
①const { name, age: years, role = 'guest' } = user를 실행하면 name은 같은 이름의 속성에서, years는 age 속성에서 값을 받아요. user에 role이 없으니 role에는 기본값 'guest'가 들어가요. 꺼내지 않은 city는 그대로 남아요.

깊이 들어 있는 값도 모양을 따라 꺼낼 수 있어요. 다만 중간 단계가 없으면 오류가 나요. 서버 응답처럼 빠질 수 있는 값은 중첩 구조 분해 대신 ?.로 읽거나, 중간 단계에 기본값 = {}을 줘요(옵셔널 체이닝).

const res = { data: { profile: { nickname: '하늘' } } };
const { data: { profile: { nickname } } } = res;
console.log(nickname);                     // 하늘

const { address: { city } } = { name: '가람' }; // address가 없으면?

나머지 ...는 객체에서도 돼요. 꺼낸 속성을 뺀 나머지가 새 객체로 모여요. 비밀번호 · 토큰처럼 화면이나 로그에 내보내면 안 되는 필드를 빼는 데 자주 써요. 원래 객체는 그대로예요.

const account = { id: 7, email: 'sky@example.com', password: 'secret', token: 'abc' };

const { password, token, ...safe } = account;
console.log(safe);                         // { id: 7, email: 'sky@example.com' }

03. 함수 매개변수에서 바로 꺼내기

실무에서 구조 분해를 가장 많이 쓰는 곳은 함수 매개변수예요. 인자가 여러 개인 함수는 createButton('저장', 'md', true)처럼 부르면 무엇이 무엇인지 알 수 없어요. 대신 객체 하나를 받아 매개변수 자리에서 꺼내면, 부르는 쪽은 이름을 붙여 넘기고 순서도 신경 쓰지 않아도 돼요. 기본값도 그 자리에서 정해요.

function createButton({ label = '버튼', size = 'md', disabled = false } = {}) {
  return `${label} · ${size} · ${disabled ? '꺼짐' : '켜짐'}`;
}

console.log(createButton({ label: '저장', disabled: true })); // 저장 · md · 꺼짐
console.log(createButton());                                 // 버튼 · md · 켜짐

끝의 = {}가 중요해요. 이게 없으면 인자 없이 createButton()을 부를 때 undefined를 구조 분해하려다 TypeError가 나요. React 컴포넌트가 function Card({ title, children })처럼 props를 받는 것도 같은 문법이에요.

아래 응답에서 닉네임, 첫 글 제목, 현재 페이지, 전체 개수를 꺼내려고 해요. 응답에 total이 없을 수도 있어서 없으면 0으로 해요. 구조 분해 한 줄로 네 변수를 만들어 하늘 첫 글 1 0이 나오게 해 보세요.

const res = {
  data: { user: { id: 7, nickname: '하늘' }, posts: [{ title: '첫 글' }, { title: '둘째 글' }] },
  meta: { page: 1 },
};

const nickname = res.data.user.nickname;
const firstTitle = res.data.posts[0].title;
const page = res.meta.page;
const total = res.meta.total ?? 0;

console.log(nickname, firstTitle, page, total);
해답 보기

객체는 속성 이름으로, 배열은 자리로 꺼내요. 첫 글은 posts 배열의 첫 자리라서 posts: [{ title: firstTitle }]처럼 배열 안에 객체 모양을 다시 써요. total은 기본값으로 처리해요. 한 줄로 쓸 수 있지만, 실무에서는 너무 깊어지면 두세 줄로 나누는 편이 읽기 쉬워요.

const { data: { user: { nickname }, posts: [{ title: firstTitle }] }, meta: { page, total = 0 } } = res;
// 하늘 첫 글 1 0

04. 실전 포인트

  • 언제 쓰나요? 인자가 셋 이상이거나 선택 인자가 있는 함수는 옵션 객체 + 매개변수 구조 분해로 받아요. 짝을 돌려주는 값(entries, useState)은 배열 구조 분해, 필드 빼기는 객체 나머지 ...를 써요.
  • 대신 쓰는 것: 빠질 수 있는 깊은 값은 중첩 구조 분해보다 ?.와 ??가 안전해요. 한두 개만 쓰는 값은 그냥 user.name으로 읽어도 충분해요.
  • 흔한 실수: 매개변수 구조 분해에 = {}를 빠뜨리는 것, 기본값이 null에도 적용될 거라 생각하는 것, 중간 단계가 없는 중첩 구조 분해, 이름 바꾸기(age: years)를 기본값으로 착각하는 것이에요.

정리

  • 배열 구조 분해는 순서로, 객체 구조 분해는 이름으로 꺼내요.
  • 속성: 새이름은 이름 바꾸기, = 값은 기본값이에요. 기본값은 undefined일 때만 쓰여요.
  • ...나머지로 남은 항목 · 속성을 모아요. 필드를 뺀 새 객체를 만들 때 좋아요.
  • 함수는 ({ a, b = 1 } = {})처럼 옵션 객체를 받아 매개변수에서 꺼내요.
const { age: years } = user;에서 만들어지는 변수는 무엇일까요?

years 하나예요. user.age의 값을 years라는 이름으로 받아요. age라는 변수는 생기지 않아요.

const { theme = 'light' } = { theme: null };이면 theme은 무엇일까요?

null이에요. 기본값은 값이 undefined일 때만 쓰여요. null도 기본값으로 바꾸고 싶으면 ?? 'light'를 따로 써요.

function f({ a }) {}를 인자 없이 f()로 부르면 어떻게 될까요?

undefined에서 a를 꺼내려다 TypeError가 나요. function f({ a } = {})처럼 매개변수 전체에 기본값 {}을 줘요.

SIMPLE · 기술스택 / JavaScript — 5장 자료구조와 자료형