JavaScript · 5장 자료구조와 자료형
구조 분해: 배열과 객체에서 필요한 값만 꺼내기
const name = user.name; const age = user.age;처럼 같은 이름을 두 번씩 쓰는 코드를 한 줄로 줄이는 문법이 구조 분해예요. 앞 글들에서 const [y, m, d] = …나 for (const [k, v] of …)로 조금씩 봤던 그 문법을, 실무에서 쓰는 모양별로 정리해요.
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 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 } = {})처럼 매개변수 전체에 기본값 {}을 줘요.