본문으로 건너뛰기
Advertisement

2.5 구조 분해 할당 (Destructuring)

구조 분해 할당이란?

**구조 분해 할당(Destructuring Assignment)**은 배열이나 객체의 값을 개별 변수로 추출하는 ES6 문법입니다. 코드를 훨씬 간결하고 읽기 쉽게 만들어줍니다.

// 기존 방식
const arr = [1, 2, 3];
const first = arr[0];
const second = arr[1];

// 구조 분해
const [a, b, c] = [1, 2, 3];

배열 구조 분해

기본 사용법

const colors = ["빨강", "초록", "파랑"];

// 기본 구조 분해
const [red, green, blue] = colors;
console.log(red); // "빨강"
console.log(green); // "초록"
console.log(blue); // "파랑"

// 일부만 추출
const [first, second] = colors;
console.log(first); // "빨강"
console.log(second); // "초록"

// 건너뛰기
const [, , third] = colors;
console.log(third); // "파랑"

const [r, , b] = colors;
console.log(r, b); // "빨강" "파랑"

기본값 설정

const [a = 1, b = 2, c = 3] = [10, 20];
console.log(a); // 10 (할당된 값 사용)
console.log(b); // 20 (할당된 값 사용)
console.log(c); // 3 (기본값 사용 - undefined였으므로)

// 실용적 예시
const [status = "pending", data = null] = getResult();

나머지 패턴 (rest)

const numbers = [1, 2, 3, 4, 5];

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

const [first, second, ...rest] = numbers;
console.log(first); // 1
console.log(second); // 2
console.log(rest); // [3, 4, 5]

// 나머지는 항상 마지막에!
// const [...rest, last] = numbers; // SyntaxError!

변수 교환 (Swap)

let x = 1;
let y = 2;

// 기존 방식 (임시 변수 필요)
let temp = x;
x = y;
y = temp;

// 구조 분해 방식 (우아함!)
[x, y] = [y, x];
console.log(x, y); // 2 1

// 실용적 예: 정렬 알고리즘
function bubbleSort(arr) {
for (let i = 0; i < arr.length; i++) {
for (let j = 0; j < arr.length - i - 1; j++) {
if (arr[j] > arr[j + 1]) {
[arr[j], arr[j + 1]] = [arr[j + 1], arr[j]]; // 교환!
}
}
}
return arr;
}

중첩 배열 구조 분해

const matrix = [[1, 2], [3, 4], [5, 6]];

const [[a, b], [c, d]] = matrix;
console.log(a, b, c, d); // 1 2 3 4

// 실용적 예: 좌표 쌍
const points = [[0, 0], [1, 5], [3, 2]];
for (const [x, y] of points) {
console.log(`좌표: (${x}, ${y})`);
}

객체 구조 분해

기본 사용법

const user = {
name: "김철수",
age: 25,
email: "chulsoo@example.com",
};

// 기본 구조 분해 (키 이름으로 변수 생성)
const { name, age, email } = user;
console.log(name); // "김철수"
console.log(age); // 25
console.log(email); // "chulsoo@example.com"

새 변수명으로 추출

const { name: userName, age: userAge } = user;
console.log(userName); // "김철수"
console.log(userAge); // 25
// name, age 변수는 생성되지 않음

// API 응답에서 유용
const { data: responseData, status: statusCode } = await fetch('/api/user');

기본값 설정

const config = { theme: "dark" };

const {
theme = "light",
language = "ko",
fontSize = 14,
} = config;

console.log(theme); // "dark" (config에 있으므로)
console.log(language); // "ko" (기본값 사용)
console.log(fontSize); // 14 (기본값 사용)

// 새 변수명 + 기본값 조합
const { theme: appTheme = "light" } = config;
console.log(appTheme); // "dark"

나머지 패턴

const { a, b, ...others } = { a: 1, b: 2, c: 3, d: 4 };
console.log(a); // 1
console.log(b); // 2
console.log(others); // { c: 3, d: 4 }

// 객체에서 특정 키 제외
const { password, ...safeUser } = userWithPassword;
// safeUser에는 password 없음

중첩 객체 구조 분해

const person = {
name: "이영희",
address: {
city: "부산",
district: "해운대구",
zip: "48085",
},
contact: {
email: "younghee@example.com",
phone: "010-1234-5678",
},
};

// 중첩 구조 분해
const {
name,
address: { city, district },
contact: { email },
} = person;

console.log(name); // "이영희"
console.log(city); // "부산"
console.log(district); // "해운대구"
console.log(email); // "younghee@example.com"
// address, contact 변수는 생성되지 않음!

// address도 변수로 받고 싶다면
const { address, address: { city: cityName } } = person;

함수 파라미터 구조 분해

객체 파라미터 구조 분해

// 기존 방식
function createUser(options) {
const name = options.name;
const age = options.age || 0;
const role = options.role || "user";
}

// 구조 분해 방식
function createUser({ name, age = 0, role = "user" }) {
console.log(`${name} (${age}) - ${role}`);
}

createUser({ name: "철수", age: 25 });
// "철수 (25) - user"

createUser({ name: "영희", role: "admin" });
// "영희 (0) - admin"

// React에서 자주 사용하는 패턴
function Button({ label, onClick, disabled = false, className = "" }) {
return `<button class="${className}" ${disabled ? 'disabled' : ''} >${label}</button>`;
}

배열 파라미터 구조 분해

function getCoordinates([x, y, z = 0]) {
return { x, y, z };
}

console.log(getCoordinates([1, 2])); // { x: 1, y: 2, z: 0 }
console.log(getCoordinates([1, 2, 3])); // { x: 1, y: 2, z: 3 }

// 나머지 파라미터와 결합
function sum([first, ...rest]) {
return rest.reduce((acc, val) => acc + val, first);
}
console.log(sum([1, 2, 3, 4, 5])); // 15

for...of에서 구조 분해

const users = [
{ id: 1, name: "김철수", role: "admin" },
{ id: 2, name: "이영희", role: "user" },
{ id: 3, name: "박민수", role: "user" },
];

// 각 사용자 순회
for (const { id, name, role } of users) {
console.log(`${id}: ${name} (${role})`);
}
// 1: 김철수 (admin)
// 2: 이영희 (user)
// 3: 박민수 (user)

// Map 순회
const map = new Map([["a", 1], ["b", 2], ["c", 3]]);
for (const [key, value] of map) {
console.log(`${key}: ${value}`);
}

// Object.entries() 순회
const obj = { x: 10, y: 20, z: 30 };
for (const [key, value] of Object.entries(obj)) {
console.log(`${key} = ${value}`);
}

실전 예제: API 응답 처리

// API 응답 데이터
const apiResponse = {
status: 200,
data: {
user: {
id: 42,
name: "김철수",
profile: {
avatar: "/images/user42.jpg",
bio: "JavaScript 개발자",
},
},
posts: [
{ id: 1, title: "JS 입문", likes: 45 },
{ id: 2, title: "비동기 처리", likes: 82 },
],
pagination: {
total: 50,
page: 1,
perPage: 10,
},
},
};

// 구조 분해로 깔끔하게 추출
const {
status,
data: {
user: {
id: userId,
name: userName,
profile: { avatar, bio },
},
posts,
pagination: { total, page },
},
} = apiResponse;

console.log(status); // 200
console.log(userId); // 42
console.log(userName); // "김철수"
console.log(avatar); // "/images/user42.jpg"
console.log(bio); // "JavaScript 개발자"
console.log(posts[0]); // { id: 1, title: "JS 입문", likes: 45 }
console.log(total); // 50

고수 팁

함수 반환값 구조 분해

// 여러 값 반환 (배열)
function minMax(arr) {
return [Math.min(...arr), Math.max(...arr)];
}

const [min, max] = minMax([3, 1, 4, 1, 5, 9, 2, 6]);
console.log(min, max); // 1 9

// 여러 값 반환 (객체) - 이름으로 접근 가능
function parseDate(dateStr) {
const [year, month, day] = dateStr.split('-').map(Number);
return { year, month, day };
}

const { year, month, day } = parseDate("2024-03-15");
console.log(year, month, day); // 2024 3 15

동적 키 구조 분해

const key = "name";
const { [key]: value } = { name: "김철수" };
console.log(value); // "김철수"

// 환경 변수 처리
function getEnvVar(varName, defaultValue = "") {
const { [varName]: value = defaultValue } = process.env;
return value;
}

const port = getEnvVar("PORT", "3000");
const apiKey = getEnvVar("API_KEY");
Advertisement