본문 바로가기

구조 분해 할당과 스프레드 연산자

배열·객체에서 필요한 값을 구조 분해하고 스프레드로 복사·결합·함수 인수 전달을 간결하게 처리합니다.

우리는 8장을 통해 let, const로 변수 선언을 개선하고, 화살표 함수로 코드 작성 방식을 더 간결하고 예측 가능하게 만들었습니다.

이제 데이터 처리 방식 자체를 크게 바꿔준 다음 핵심 기능으로 넘어갑니다.

구조 분해 할당(Destructuring Assignment)과 스프레드 연산자(Spread Operator)는 배열이나 객체에서 데이터를 추출하거나, 배열이나 객체를 복사/결합할 때 사용되는 문법입니다.

이 두 기능은 코드를 훨씬 간결하고 가독성 높게 만들어주며, 데이터를 다루는 다양한 상황에서 개발자의 편의성을 극대화합니다.

이번 장에서는 구조 분해 할당으로 값 추출하기, 스프레드 연산자로 배열/객체 다루기를 중심으로 핵심 패턴을 정리합니다.


구조 분해 할당

먼저 객체와 배열의 참조 공유를 떠올려 보세요. 값을 다른 이름에 연결하는 일과 새 바깥 객체를 만드는 일은 다릅니다. 아래 코드 블록은 별개의 예제이므로 같은 이름의 const 선언을 한 파일에 모두 붙이지 않습니다.

구조 분해 할당 (Destructuring Assignment)은 배열이나 객체의 속성(property)을 해체하여 그 값을 개별 변수에 할당할 수 있게 하는 자바스크립트 표현식입니다.

복잡한 데이터 구조에서 필요한 값만 깔끔하게 추출할 때 매우 유용합니다.

배열 구조 분해 (Array Destructuring)

배열의 각 요소를 해체하여 변수에 할당할 수 있습니다.

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

// 배열 구조 분해 할당
const [firstColor, secondColor, thirdColor] = colors;

console.log(firstColor);  // 결과: "red"
console.log(secondColor); // 결과: "green"
console.log(thirdColor);  // 결과: "blue"
다양한 활용
  • 일부 값만 추출: 필요한 요소만 선택적으로 가져올 수 있습니다. 건너뛰고 싶은 요소는 쉼표로 비워둡니다.

    const numbers = [10, 20, 30, 40, 50];
    const [a, , c, , e] = numbers; // 두 번째와 네 번째 요소 건너뛰기
    console.log(a); // 결과: 10
    console.log(c); // 결과: 30
    console.log(e); // 결과: 50
  • 기본값 설정: 할당할 값이 undefined일 경우에 대비하여 기본값을 설정할 수 있습니다.

    const fruits = ["apple"];
    const [myFruit, otherFruit = "orange"] = fruits;
    console.log(myFruit);    // 결과: "apple"
    console.log(otherFruit); // 결과: "orange" (fruits 배열에 두 번째 요소가 없으므로 기본값 사용)
    const [item1, item2 = "default"] = [];
    console.log(item1); // 결과: undefined
    console.log(item2); // 결과: "default"
  • 나머지 요소 가져오기 (...rest): 배열의 나머지 요소들을 새로운 배열로 묶을 수 있습니다. (스프레드 연산자와 동일한 문법이지만 여기서는 rest 요소 역할)

    const scores = [80, 90, 70, 60, 95];
    const [math, english, ...restScores] = scores;
    console.log(math);       // 결과: 80
    console.log(english);    // 결과: 90
    console.log(restScores); // 결과: [70, 60, 95] (새로운 배열)
  • 변수 값 교환: 임시 변수 없이 두 변수의 값을 쉽게 교환할 수 있습니다.

    let x = 1;
    let y = 2;
    [x, y] = [y, x]; // x와 y의 값을 교환
    console.log(x); // 결과: 2
    console.log(y); // 결과: 1

객체 구조 분해 (Object Destructuring)

객체의 프로퍼티를 해체하여 변수에 할당할 수 있습니다.

축약형에서는 프로퍼티 이름을 변수 이름으로 쓰고, key: localName 형태로 다른 변수 이름을 지정할 수도 있습니다.

const person = {
    name: "Alice",
    age: 30,
    city: "New York"
};

// 객체 구조 분해 할당
const { name, age } = person;

console.log(name); // 결과: "Alice"
console.log(age);  // 결과: 30
// console.log(city); // ReferenceError: city is not defined (city는 할당하지 않음)
다양한 활용
  • 다른 이름으로 할당: 객체의 프로퍼티 이름과 다른 이름으로 변수를 선언하고 싶을 때 사용합니다.

    const { name: userName, age: userAge } = person;
    console.log(userName); // 결과: "Alice"
    console.log(userAge);  // 결과: 30
  • 기본값 설정: 할당할 프로퍼티가 undefined일 경우에 대비하여 기본값을 설정할 수 있습니다.

    const { country = "Korea", age } = person; // person 객체에 country 프로퍼티가 없으므로 기본값 사용
    console.log(country); // 결과: "Korea"
    console.log(age);     // 결과: 30
  • 나머지 프로퍼티 가져오기 (...rest): 객체의 나머지 프로퍼티들을 새로운 객체로 묶을 수 있습니다.

    const { name, ...restInfo } = person;
    console.log(name);     // 결과: "Alice"
    console.log(restInfo); // 결과: { age: 30, city: "New York" } (새로운 객체)
  • 중첩된 객체 구조 분해: 중첩된 객체에서 깊숙이 있는 프로퍼티를 한 번에 추출할 수 있습니다.

    const userProfile = {
        id: 1,
        userInfo: {
            fullName: "Bob Johnson",
            email: "[email protected]"
        },
        preferences: {
            theme: "dark"
        }
    };
    const {
        userInfo: { fullName, email }, // userInfo 객체를 분해하여 fullName, email 추출
        preferences: { theme: userTheme } // preferences 객체를 분해하여 theme를 userTheme으로 추출
    } = userProfile;
    console.log(fullName);   // 결과: "Bob Johnson"
    console.log(email);      // 결과: "[email protected]"
    console.log(userTheme);  // 결과: "dark"
  • 함수 매개변수에서의 구조 분해: 함수의 매개변수에서 객체나 배열을 직접 구조 분해하여 사용할 수 있어 코드가 더욱 간결해집니다.

    // 객체 매개변수 구조 분해
    function displayUser({ name, age }) {
        console.log(`이름: ${name}, 나이: ${age}`);
    }
    const myUser = { name: "철수", age: 25 };
    displayUser(myUser); // 결과: 이름: 철수, 나이: 25
    // 배열 매개변수 구조 분해
    function printCoordinates([x, y]) {
        console.log(`X: ${x}, Y: ${y}`);
    }
    const point = [10, 20];
    printCoordinates(point); // 결과: X: 10, Y: 20

스프레드 연산자 ...

배열 리터럴과 함수 인수의 스프레드는 이터러블의 순회로 얻은 원소를 펼칩니다. 객체 리터럴의 스프레드는 대상의 열거 가능한 자체 프로퍼티 값을 새 객체에 넣습니다. 모양은 같아도 일반 객체를 배열처럼 순회하는 규칙은 아닙니다.

배열, 객체, 함수의 인자 등 다양한 곳에서 활용됩니다.

배열에서의 스프레드 연산자

  • 배열 결합 (Concatenation): 여러 배열을 쉽게 결합할 수 있습니다.

    const arr1 = [1, 2];
    const arr2 = [3, 4];
    const combinedArr = [...arr1, ...arr2];
    console.log(combinedArr); // 결과: [1, 2, 3, 4]
    const newArr = [0, ...arr1, 5, ...arr2];
    console.log(newArr); // 결과: [0, 1, 2, 5, 3, 4]
  • 배열 복사 (Shallow Copy): 원본 배열을 변경하지 않고 새로운 배열의 사본을 만들 수 있습니다. (얕은 복사임에 유의)

    const original = [1, 2, 3];
    const copy = [...original];
    console.log(copy);          // 결과: [1, 2, 3]
    console.log(original === copy); // 결과: false (다른 메모리 주소)
    copy.push(4);
    console.log(original); // 결과: [1, 2, 3] (원본 불변)
  • 배열 요소 추가/삽입: 배열의 특정 위치에 요소를 쉽게 추가하거나 삽입할 수 있습니다.

    const baseArray = [1, 2, 3];
    const newArrayAtStart = [0, ...baseArray]; // 맨 앞에 추가
    console.log(newArrayAtStart); // 결과: [0, 1, 2, 3]
    const newArrayAtMiddle = [1, ...baseArray.slice(1, 2), 99, ...baseArray.slice(2)]; // 중간에 삽입 (복잡)
    console.log(newArrayAtMiddle); // 결과: [1, 2, 99, 3]
    // 실용적으로는 splice나 map, filter를 조합하는 경우가 많음
  • 이터러블을 배열로 변환: 이터러블(예: Set, String)을 배열로 쉽게 변환할 수 있습니다. length와 숫자 키만 있는 유사 배열 객체는 iterable이 아니므로, 그 경우에는 Array.from() 같은 변환이 필요합니다.

    const myString = "hello";
    const charArray = [...myString];
    console.log(charArray); // 결과: ["h", "e", "l", "l", "o"]
    const mySet = new Set([1, 2, 3]);
    const setToArray = [...mySet];
    console.log(setToArray); // 결과: [1, 2, 3]

객체에서의 스프레드 연산자 (ES2018부터)

  • 객체 병합 (Object Merging): 여러 객체를 병합하여 새로운 객체를 만들 수 있습니다.

    const user = { name: "John", age: 30 };
    const address = { city: "Seoul", zip: "12345" };
    const details = { job: "Developer" };
    const fullProfile = { ...user, ...address, ...details };
    console.log(fullProfile);
    // 결과: { name: 'John', age: 30, city: 'Seoul', zip: '12345', job: 'Developer' }

    이때 동일한 키가 있으면 뒤에 오는 객체의 값으로 앞의 값을 덮어씁니다.

    const objA = { a: 1, b: 2 };
    const objB = { b: 3, c: 4 };
    const mergedObj = { ...objA, ...objB };
    console.log(mergedObj); // 결과: { a: 1, b: 3, c: 4 } (b가 덮어써짐)
  • 객체 복사 (Shallow Copy): 원본 객체를 변경하지 않고 새로운 객체의 사본을 만들 수 있습니다. (얕은 복사임에 유의)

    const originalObj = { x: 1, y: 2 };
    const copyObj = { ...originalObj };
    console.log(copyObj);          // 결과: { x: 1, y: 2 }
    console.log(originalObj === copyObj); // 결과: false
    copyObj.x = 10;
    console.log(originalObj.x); // 결과: 1 (원본 불변)
  • 객체 프로퍼티 추가/업데이트: 기존 객체에 새로운 프로퍼티를 추가하거나, 특정 프로퍼티 값을 업데이트할 때 유용합니다.

    const product = { id: 1, name: "Laptop", price: 1200 };
    const updatedProduct = { ...product, price: 1100, category: "Electronics" };
    console.log(updatedProduct);
    // 결과: { id: 1, name: 'Laptop', price: 1100, category: 'Electronics' }

함수 호출 시 스프레드 연산자 (...args)

함수에 배열의 요소들을 개별적인 인자로 전달할 때 사용합니다.

(이때는 나머지 파라미터와는 다름)

function sum(a, b, c) {
    return a + b + c;
}

const numbersToSum = [1, 2, 3];
const result = sum(...numbersToSum); // 배열 요소를 개별 인자로 펼쳐서 전달
console.log(result); // 결과: 6

위 원시 값 배열·객체 예제에서는 새 바깥 구조를 수정해도 원본 값이 그대로입니다. 그러나 ===는 물리적 메모리 주소 대신 객체의 동일성을 비교하며, 내부 객체 참조를 공유하면 그 내부 변경은 원본에서도 보입니다.

구조 분해와 spread의 복사 경계 — 상태 추적

원본/구조 분해/rest/spread가 같은 settings를 가리켜 내부 theme 변경을 공유한다. 별개의 연산을 직렬이라고 주장하지 않고, 준비된 참조 전체에서 변경 전후 관찰값을 비교하는 trace가 유용하다.

구조 분해와 spread의 복사 경계

REFERENCE GRAPH

구조 분해와 spread의 복사 경계

구조 분해는 값을 이름에 연결한다. rest와 spread는 새 바깥 객체·배열을 만들지만, 그 안의 객체 참조는 공유한다.

새 바깥 구조와 공유된 내부 객체원본 source의 settings 프로퍼티, 구조 분해로 선택한 settings 이름, name을 제외한 rest 새 객체, spread 새 객체가 하나의 내부 settings 객체를 참조합니다. 네 연산은 같은 원본에 별도로 적용한 비교이며 실행 순서를 나타내지 않습니다. rest와 spread는 새 바깥 객체를 만들고, 구조 분해는 컨테이너를 복사하지 않습니다. 모바일도 하나의 내부 객체로 향하는 네 참조와 별개 바깥 영역을 유지합니다. 배열 spread도 내부 객체를 공유하지만 그림은 객체 settings 사례에 한정합니다. 별개 연산을 같은 원본에 적용한 관계 비교같은 settings 객체theme: "dark"내부 변경을 공유원본 sourcesettings 프로퍼티구조 분해 이름const {settings} = source새 객체 복사 없음rest 바깥 객체const {name, ...rest} = source새 바깥 객체spread 바깥 객체const copy = {...source}새 바깥 객체각 화살표는 내부 객체 참조 · 연산 실행 순서가 아님
새 바깥 구조와 공유된 내부 객체원본 source의 settings 프로퍼티, 구조 분해로 선택한 settings 이름, name을 제외한 rest 새 객체, spread 새 객체가 하나의 내부 settings 객체를 참조합니다. 네 연산은 같은 원본에 별도로 적용한 비교이며 실행 순서를 나타내지 않습니다. rest와 spread는 새 바깥 객체를 만들고, 구조 분해는 컨테이너를 복사하지 않습니다. 모바일도 하나의 내부 객체로 향하는 네 참조와 별개 바깥 영역을 유지합니다. 배열 spread도 내부 객체를 공유하지만 그림은 객체 settings 사례에 한정합니다.같은 원본으로 별개 연산같은 settings내부 객체 하나변경을 공유원본 sourcesettings 프로퍼티구조 분해 이름새 객체 없음rest 바깥 객체새 바깥 객체spread 바깥 객체새 바깥 객체네 참조 모두 같은 내부 객체새 바깥 구조 ≠ 깊은 복사

const {name} = source

새 container 만들지 않음

nested identity name 값이 object면 같은 nested reference

const {skip, ...rest} = source

새 container 새 object outer

nested identity nested object는 원본과 공유

const copy = {...source}

새 container 새 object outer

nested identity enumerable own property를 얕게 복사하며 내부 객체 참조는 공유

const copy = [...source]

새 container 새 array outer

nested identity element object identity는 공유

  • 연산별 참조 공유 비교
  • rest·spread의 새 바깥 구조

새 바깥 구조 · 같은 내부 객체

rest와 spread의 결과는 원본과 다른 객체·배열이다. 내부 객체를 변경하면 공유된 참조를 통해 원본에서도 그 변경이 보일 수 있다.

destructuring은 container 복사 문법이 아니며, rest와 spread도 기본적으로 outer만 새로 만든다. nested graph까지 독립시키지는 않는다.

이 예의 조건

  • 원도표의 전체 구조와 설명은 위 관계도와 표에서 유지합니다. 아래 인쇄 표에도 원도표의 관계·조건·라벨·설명·주석을 보존합니다.
  • 두 관찰 칸의 위치는 고정입니다. 관찰 상태는 해당 순간의 값이며, 동작·이유는 그 조건에서의 판정과 변화 원인입니다. 독립 비교와 실패 분기는 별도 조건으로 읽고 모든 분기를 한 요청의 필수 실행 순서로 이어 읽지 않습니다.
관계도의 보충 설명
원도표의 전체 관계·조건·설명
구분내용
원도표 설명새 container: 만들지 않음
원도표 설명nested identity: name 값이 object이면 같은 nested reference
원도표 설명새 container: 새 object outer
원도표 설명nested identity: nested object는 원본과 공유
원도표 설명nested identity: enumerable own property를 얕게 복사하며 내부 객체 참조는 공유
원도표 설명새 container: 새 array outer
원도표 설명nested identity: element object identity는 공유
전체 상태와 변화 근거
장면현재 관찰값설명변화 이유
공유 입력outer: 서로 다른 결과 가능 / settings: 같은 참조source와 독립 복사 결과의 settings는 같은 내부 객체다rest/spread는 내부 객체의 깊은 복사가 아니다
내부 변경settings.theme: dark / 독립 outer: 그대로한 경로에서 settings.theme을 바꾼다공유 참조를 통한 변경이다
공유 결과관찰: 모든 공유 settings dark / 생성 동작: 서로 독립적인 사례다른 경로도 theme:dark를 읽는다여러 복사 문법을 반드시 순차 실행해야 한다는 뜻은 아니다

구조 분해와 spread의 복사 경계 — 상태 추적

원본/구조 분해/rest/spread가 같은 settings를 가리켜 내부 theme 변경을 공유한다. 별개의 연산을 직렬이라고 주장하지 않고, 준비된 참조 전체에서 변경 전후 관찰값을 비교하는 trace가 유용하다.

구조 분해와 spread의 복사 경계

REFERENCE GRAPH

구조 분해와 spread의 복사 경계

구조 분해는 값을 이름에 연결한다. rest와 spread는 새 바깥 객체·배열을 만들지만, 그 안의 객체 참조는 공유한다.

새 바깥 구조와 공유된 내부 객체원본 source의 settings 프로퍼티, 구조 분해로 선택한 settings 이름, name을 제외한 rest 새 객체, spread 새 객체가 하나의 내부 settings 객체를 참조합니다. 네 연산은 같은 원본에 별도로 적용한 비교이며 실행 순서를 나타내지 않습니다. rest와 spread는 새 바깥 객체를 만들고, 구조 분해는 컨테이너를 복사하지 않습니다. 모바일도 하나의 내부 객체로 향하는 네 참조와 별개 바깥 영역을 유지합니다. 배열 spread도 내부 객체를 공유하지만 그림은 객체 settings 사례에 한정합니다. 별개 연산을 같은 원본에 적용한 관계 비교같은 settings 객체theme: "dark"내부 변경을 공유원본 sourcesettings 프로퍼티구조 분해 이름const {settings} = source새 객체 복사 없음rest 바깥 객체const {name, ...rest} = source새 바깥 객체spread 바깥 객체const copy = {...source}새 바깥 객체각 화살표는 내부 객체 참조 · 연산 실행 순서가 아님
새 바깥 구조와 공유된 내부 객체원본 source의 settings 프로퍼티, 구조 분해로 선택한 settings 이름, name을 제외한 rest 새 객체, spread 새 객체가 하나의 내부 settings 객체를 참조합니다. 네 연산은 같은 원본에 별도로 적용한 비교이며 실행 순서를 나타내지 않습니다. rest와 spread는 새 바깥 객체를 만들고, 구조 분해는 컨테이너를 복사하지 않습니다. 모바일도 하나의 내부 객체로 향하는 네 참조와 별개 바깥 영역을 유지합니다. 배열 spread도 내부 객체를 공유하지만 그림은 객체 settings 사례에 한정합니다.같은 원본으로 별개 연산같은 settings내부 객체 하나변경을 공유원본 sourcesettings 프로퍼티구조 분해 이름새 객체 없음rest 바깥 객체새 바깥 객체spread 바깥 객체새 바깥 객체네 참조 모두 같은 내부 객체새 바깥 구조 ≠ 깊은 복사

const {name} = source

새 container 만들지 않음

nested identity name 값이 object면 같은 nested reference

const {skip, ...rest} = source

새 container 새 object outer

nested identity nested object는 원본과 공유

const copy = {...source}

새 container 새 object outer

nested identity enumerable own property를 얕게 복사하며 내부 객체 참조는 공유

const copy = [...source]

새 container 새 array outer

nested identity element object identity는 공유

  • 연산별 참조 공유 비교
  • rest·spread의 새 바깥 구조

새 바깥 구조 · 같은 내부 객체

rest와 spread의 결과는 원본과 다른 객체·배열이다. 내부 객체를 변경하면 공유된 참조를 통해 원본에서도 그 변경이 보일 수 있다.

destructuring은 container 복사 문법이 아니며, rest와 spread도 기본적으로 outer만 새로 만든다. nested graph까지 독립시키지는 않는다.

이 예의 조건

  • 원도표의 전체 구조와 설명은 위 관계도와 표에서 유지합니다. 아래 인쇄 표에도 원도표의 관계·조건·라벨·설명·주석을 보존합니다.
  • 두 관찰 칸의 위치는 고정입니다. 관찰 상태는 해당 순간의 값이며, 동작·이유는 그 조건에서의 판정과 변화 원인입니다. 독립 비교와 실패 분기는 별도 조건으로 읽고 모든 분기를 한 요청의 필수 실행 순서로 이어 읽지 않습니다.

관계도의 보충 설명

원도표의 전체 관계·조건·설명
구분내용
원도표 설명새 container: 만들지 않음
원도표 설명nested identity: name 값이 object이면 같은 nested reference
원도표 설명새 container: 새 object outer
원도표 설명nested identity: nested object는 원본과 공유
원도표 설명nested identity: enumerable own property를 얕게 복사하며 내부 객체 참조는 공유
원도표 설명새 container: 새 array outer
원도표 설명nested identity: element object identity는 공유
전체 상태와 변화 근거
장면현재 관찰값설명변화 이유
공유 입력outer: 서로 다른 결과 가능 / settings: 같은 참조source와 독립 복사 결과의 settings는 같은 내부 객체다rest/spread는 내부 객체의 깊은 복사가 아니다
내부 변경settings.theme: dark / 독립 outer: 그대로한 경로에서 settings.theme을 바꾼다공유 참조를 통한 변경이다
공유 결과관찰: 모든 공유 settings dark / 생성 동작: 서로 독립적인 사례다른 경로도 theme:dark를 읽는다여러 복사 문법을 반드시 순차 실행해야 한다는 뜻은 아니다

기본값이 적용되는 조건 기본값은 값이 없거나 undefined일 때만 적용됩니다. null은 그대로 남으며, 분해할 대상 자체가 null 또는 undefined이면 프로퍼티를 읽을 수 없어 TypeError가 발생합니다. 중첩 패턴도 중간 객체가 존재해야 합니다.

const { theme: first = "light" } = { theme: undefined };
const { theme: second = "light" } = { theme: null };
console.log(first, second);

출력은 light null입니다. null도 기본값으로 바꿔야 하는 요구라면 구조 분해의 =만으로 해결되는지 먼저 검토해야 합니다.

예시 바깥 객체와 내부 설정 객체의 동일성을 따로 확인해 봅시다.

const originalSettings = { name: "원본", settings: { theme: "dark" } };
const { settings } = originalSettings;
const copiedSettings = { ...originalSettings, name: "복사본" };
copiedSettings.settings.theme = "light";
console.log(originalSettings === copiedSettings);
console.log(settings === copiedSettings.settings);
console.log(originalSettings.name, originalSettings.settings.theme);

출력은 false, true, 원본 light입니다. 스프레드는 새 바깥 객체를 만들지만 settings의 값은 같은 내부 객체에 대한 참조입니다. 구조 분해 역시 그 내부 객체를 복제하지 않습니다.

스스로 확인하기 복사 선언을 const copiedSettings = { ...originalSettings, settings: { ...originalSettings.settings }, name: "복사본" };로 바꾼 뒤 처음부터 실행하면 세 출력은 어떻게 달라지나요? 이 변경이 모든 깊이의 복사를 보장하는지도 생각해 보세요.

풀이 확인

false, false, 원본 dark입니다. 이 예제의 설정 객체까지 새로 만들었으므로 theme 변경은 복사본에만 적용됩니다. 더 깊은 객체가 있다면 그 참조는 다시 공유할 수 있어, 전체 깊은 복사라고 일반화하지 않습니다.

기본값과 대상 조건은 MDN 구조 분해 설명, 펼치는 위치별 계약은 MDN 스프레드 설명에서 확인할 수 있습니다.

구조 분해와 스프레드 정리

이번 장에서는 ES2015(ES6)에서 도입된 매우 강력하고 유용한 문법인 구조 분해 할당(Destructuring Assignment)과 스프레드 연산자(Spread Operator)에 대해 심도 있게 학습했습니다.

구조 분해 할당은 배열과 객체에서 필요한 값만 꺼낼 때 사용합니다.

스프레드 연산자는 배열 결합, 얕은 복사, 객체 병합, 함수 인자 전달처럼 값을 펼쳐 전달해야 하는 상황에서 자주 쓰입니다.

이 두 기능은 데이터를 꺼내고 합치는 코드를 짧게 만들지만, 원본 변경 여부와 얕은 복사 범위는 항상 함께 확인해야 합니다.

예제를 직접 바꿔 보며 배열과 객체에서 어떤 값이 새로 만들어지는지 확인해 보세요.


구조 분해와 스프레드는 객체와 배열을 직접 바꾸지 않고 필요한 값만 꺼내거나 새 값으로 조합하는 데 자주 쓰입니다.

마지막으로 상태나 응답 데이터를 다룰 때는 어떤 값이 추출되고 어떤 값이 새 객체로 복사되는지 한 흐름으로 확인합니다.