배열/객체 구조 분해 할당, 안전하게 쓰는 팁: 기본값과 나머지 매개변수 활용

2025-10-09

Destructuring Assignment는 배열이나 객체의 속성을 해체하여 그 값을 개별 변수에 쉽게 담을 수 있도록 해주는 문법이에요. 코드를 훨씬 간결하고 가독성 좋게 만들어주죠! 하지만 몇 가지 주의해야 할 점들이 있답니다.

가장 흔하게 발생하는 문제 중 하나예요. 비구조화 하려는 대상 객체나 배열이 null 또는 undefined일 경우, 해당 값에서 속성을 읽어오려고 하면서 에러가 발생해요.

에러 메시지 예시
TypeError: Cannot destructure property 'name' of 'undefined' or 'null'.

//  문제 상황
const user = null;

try {
  const { name, age } = user; //  여기서 에러 발생
  console.log(name, age);
} catch (e) {
  console.error(e.message); // 출력: Cannot destructure property 'name' of 'null'.
}

비구조화 할당 시 우변에 기본값을 지정해 주거나, Nullish Coalescing Operator (??)를 사용하여 대상이 null 또는 undefined일 때 빈 객체 {}를 할당하도록 할 수 있어요.

//  해결 1: Nullish Coalescing Operator (??)를 사용하여 기본값 설정
const userA = null;
const { name: nameA, age: ageA } = userA ?? {}; // userA가 null/undefined이면 {}를 사용
console.log(`이름: ${nameA}, 나이: ${ageA}`); // 출력: 이름: undefined, 나이: undefined

//  해결 2: 변수별로 기본값을 지정
const userB = null;
const { name: nameB = '알 수 없음', age: ageB = 0 } = userB ?? {};
console.log(`이름: ${nameB}, 나이: ${ageB}`); // 출력: 이름: 알 수 없음, 나이: 0

이미 선언된 변수에 객체 비구조화 할당을 사용하여 값을 재할당할 때, 괄호 ()로 감싸주지 않으면 자바스크립트는 이를 코드 블록 {}으로 해석해서 구문 오류가 발생할 수 있어요.

//  문제 상황
let x = 10, y = 20;
const obj = { x: 1, y: 2 };

// { ... }를 코드 블록으로 해석하여 에러 발생 (SyntaxError)
try {
  { x, y } = obj; 
} catch (e) {
  console.error(e.message); // 출력: Invalid left-hand side in assignment
}

변수 선언(const, let, var) 없이 이미 선언된 변수에 객체 비구조화 할당을 할 때는 할당문 전체를 괄호 ()로 감싸 자바스크립트에게 이것이 코드 블록이 아닌 할당문임을 알려줘야 해요.

//  해결: 괄호로 감싸기
let x = 10, y = 20;
const obj = { x: 1, y: 2 };

({ x, y } = obj); //  괄호로 감싸서 할당문임을 명확히 함

console.log(`x: ${x}, y: ${y}`); // 출력: x: 1, y: 2

객체의 메서드(함수)를 비구조화하여 별도의 변수에 할당하면, 그 메서드 내부의 this 값이 원래의 객체가 아닌 전역 객체(브라우저의 경우 window)를 가리키게 되어 예상치 못한 동작을 할 수 있어요.

//  문제 상황
const counter = {
  count: 0,
  increase() {
    this.count++;
    console.log(this.count);
  }
};

const { increase } = counter;

// 'increase'를 호출할 때, this가 counter 객체가 아님!
// (엄격 모드에서는 TypeError 또는 undefined.count++ 시 에러)
// 브라우저 환경에서 엄격 모드가 아니면 this.count가 전역 변수를 건드릴 수 있음.
increase(); //  예상치 못한 this 바인딩

원본 객체를 통해 메서드 호출 (가장 확실한 방법)

//  해결 1: 원본 객체를 통해 호출
counter.increase(); // this는 'counter'를 정확히 가리킵니다.

bind()를 사용하여 this를 고정

//  해결 2: bind()를 사용하여 this 고정
const { increase } = counter;
const boundIncrease = increase.bind(counter); // counter 객체로 this 고정
boundIncrease(); // 이제 this는 counter를 가리킵니다.

Destructuring이 제공하는 유용한 기능과 이를 활용하는 팁들을 알아볼게요.

객체 비구조화 시, 객체의 속성 이름과 다른 이름의 변수를 사용하고 싶을 때가 있죠. 이럴 땐 콜론 :을 사용해서 변수 이름을 바꿔 줄 수 있어요.

const person = { 
    firstName: '철수', 
    lastName: '김' 
};

// 'firstName'을 'fName'으로, 'lastName'을 'lName'으로 변경
const { firstName: fName, lastName: lName } = person; 

console.log(fName); // 출력: 철수
console.log(lName); // 출력: 김

// 대안: 기존 방식 (더 길고 반복적)
// const fName = person.firstName;
// const lName = person.lastName;

비구조화 하려는 속성이 undefined일 경우에 대비하여 기본값을 설정해 줄 수 있어요.

const item = { id: 101, price: 500 }; // name 속성 없음

// price는 객체 값 사용, name은 undefined이므로 기본값 사용
const { id, price, name = '상품명 없음', count = 1 } = item;

console.log(id);    // 출력: 101
console.log(price); // 출력: 500
console.log(name);  // 출력: 상품명 없음 (기본값 적용)
console.log(count); // 출력: 1 (기본값 적용)

배열이나 객체의 일부만 추출하고, 나머지는 새로운 배열이나 객체로 묶고 싶을 때 Rest Parameter (...)를 사용할 수 있어요.

const colors = ['빨강', '주황', '노랑', '초록', '파랑'];

const [mainColor, secondaryColor, ...otherColors] = colors;

console.log(mainColor);      // 출력: 빨강
console.log(secondaryColor); // 출력: 주황
console.log(otherColors);    // 출력: [ '노랑', '초록', '파랑' ]
const settings = {
  theme: 'dark',
  fontSize: 14,
  language: 'ko',
  timeout: 300
};

const { theme, fontSize, ...advancedSettings } = settings;

console.log(theme);           // 출력: dark
console.log(fontSize);        // 출력: 14
console.log(advancedSettings); // 출력: { language: 'ko', timeout: 300 }

javascript



자바스크립트 Temporal API 3단계: weekOfYear의 ISO 주 번호 계산 원리와 대체 방안

Temporal. PlainDate. prototype. weekOfYear는 특정 PlainDate 객체가 나타내는 날짜가 ISO 8601 표준에 따른 몇 번째 주(week)에 해당하는지를 숫자로 반환하는 속성입니다


객체 프로퍼티 충돌 방지! JavaScript Symbol vs Symbol.for() 완벽 정리

Symbol은 ES6(ECMAScript 2015)에 도입된 원시(primitive) 데이터 타입 중 하나로, 객체의 고유한 프로퍼티 키를 생성하는 데 주로 사용돼요. 이름 충돌을 피할 수 있게 해주는 아주 유용한 기능이죠!


JS 국제화(Intl) API: resolvedOptions()를 이용한 상대적 시간 포맷 설정값 디버깅

이번에 다룰 내용은 JavaScript의 국제화(Internationalization) API 중 하나인 Intl. RelativeTimeFormat. resolvedOptions()입니다. 이 메서드는 상대적인 시간 포맷을 처리하는 Intl



자바스크립트 뺄셈 대입 연산자(-=): 코드를 간결하게!

뺄셈 대입 연산자(−=)는 왼쪽 피연산자(변수)에서 오른쪽 피연산자의 값을 빼고, 그 결과를 다시 왼쪽 피연산자에 대입(할당)하는 역할을 합니다.쉽게 말해, x = x - y를 x -= y처럼 줄여 쓰는(단축하는) 문법이에요


**= 대신 쓸 수 있는 코드는? JavaScript 지수 할당 연산자의 함정과 해결책

지수 할당 연산자(∗∗=)는 JavaScript에서 지수 연산(∗∗)과 할당 연산자$(=)$를 결합한 편리한 단축 문법이에요.역할 왼쪽 피연산자(변수)의 값을 오른쪽 피연산자 값으로 거듭제곱한 다음, 그 결과를 다시 왼쪽 피연산자에 할당합니다


Temporal.PlainYearMonth.equals() 완벽 해부: 흔한 오해와 대체 코드 예시

한국어로 친절하고 자세하게 설명해 드릴게요!Temporal. PlainYearMonth. prototype. equals(other) 메서드는 호출한 PlainYearMonth 객체와 인수로 전달된 other 객체가 같은 연도


Temporal.Instant 사용 시 흔한 문제 3가지와 ZonedDateTime을 활용한 해결법

Temporal. Instant는 특정 시점, 즉 타임스탬프를 나타내는 객체예요.Temporal. Instant는 UTC(협정 세계시) 기준으로 Unix Epoch(1970년 1월 1일 000000 UTC) 이후 경과된 나노초로 표현되는 정확한 시점을 나타냅니다


세미콜론($;$)과 할당($=$) 실수 방지! JavaScript 표현식 문 완전 정복

자바스크립트의 프로그램은 여러 개의 문(Statement)으로 이루어져 있어요. 이 문들은 컴퓨터에게 "무언가를 하라"는 명령을 내리는 역할을 하죠.그중 표현식 문은 이름 그대로 "표현식(Expression)"을 포함하는 문이랍니다


Proxy defineProperty 트랩으로 객체에 유효성 검사(Validation) 적용하기

친절하고 자세하게 설명해 드릴게요.Proxy는 '대리인'이라는 뜻 그대로, 어떤 타겟 객체(target)의 모든 기본 동작(속성 읽기, 쓰기, 정의 등)을 가로채서(trap) 우리가 원하는 대로 재정의할 수 있게 해주는 객체예요


태그로 감싼 코드 블록 형태로 제공하겠습니다.

setUint32() 메서드는 ArrayBuffer라는 원시 바이너리 데이터 버퍼에 저장된 DataView 객체를 사용하여, 지정된 오프셋(byteOffset) 위치에 32비트 부호 없는 정수(unsigned 32-bit integer