Object.assign 메서드의 핵심 역할
ECMAScript 2015(ES6) 스펙에 포함된 Object.assign() 은 하나 이상의 소스(source) 객체에서 정의된 특정한 속성을 타겟(target) 객체로 복사하여 반환하는 유틸리티 함수입니다. 주로 초기 설정값과 사용자 커스터마이징 값을 통합할 때 빈번히 활용되며, 기존 객체를 변조하지 않고 새로운 상태를 생성하는 불변성 패턴 구현에도 기여합니다.
실행 문법과 인자 설명
이 메서드는 첫 번째 인자를 목적지 객체로 두고, 그 뒤에 이어지는 모든 인자들을 출처 객체로 간주합니다.
Object.assign(target, source1, source2, ...)
| 인자명 | 역할 정의 |
|---|---|
| target | 속성이 복사될 수신 객체. 반환 값은 이 객체가 됨. |
| source1, ... | 복사 원본이 되는 객체들. 여러 개를 나열 가능. |
작동 동작의 세부 규칙
객체 병합 시 발생하는 주요 현상들은 다음과 같이 정리할 수 있습니다.
- 우선순위 기반 덮어쓰기: 중복되는 키가 있을 경우, 오른쪽에 있는 출처 객체의 값이 우선 적용되어 왼쪽의 값을 대체합니다.
- 얕은 복사 (Shallow Copy): 복사 대상이 배열이나 객체인 참조 타입일 경우, 실제 데이터가 아닌 메모리 주소만 연결됩니다. 내부 값 변경 시 연쇄 반응이 발생할 수 있습니다.
- 열거 가능한 속성만 전송:
enumerable: true가 설정된 고유 속성 (own property) 만 이동하며, 프로토타입 체인을 타고 내려오는 속성은 무시됩니다. - 원시값 처리: 출처가 숫자나 문자열 같은 원시 타입이면 내부적으로 래퍼 객체로 변환된 후 처리되지만, 숫자/불린형은 복사 가능한 속성이 없어 효과적이지 않습니다. 문자열은 인덱스가 속성이 됩니다.
실무 적용 예시: 기본 설정과 오버라이드 병합
컴포넌트나 서비스의 기본값을 보존하면서 사용자가 수정한 옵션을 반영해야 할 때 아래 패턴이 가장 일반적입니다.
기존 코드에서는 빈 객체 리터럴 {} 을 타겟으로 사용하여 부작용을 차단했습니다. 이를 변수명을 변경하고 구조를 재배열하여 다시 작성해 보겠습니다.
// 기본 정책 정의 (시스템 레벨)
const systemDefaults = {
visibility: 'hidden',
timeout: 3000,
autoClose: true
};
// 사용자가 전달한 커스터마이징 값
const userPreference = {
timeout: 5000,
showIcon: false
};
// 안전 병합: 새로운 컨텍스트 생성
const activePolicy = Object.assign(
{}, // 새 컨테이너 (Side-effect 방지)
systemDefaults, // 1 단계: 기본값 주입
userPreference // 2 단계: 사용자값 덮어쓰기
);
console.log(activePolicy);
// 출력: { visibility: 'hidden', timeout: 5000, autoClose: true, showIcon: false }
위 과정에서 activePolicy.timeout 은 3000 대신 5000 으로 확정되며, 시스템 기본값 객체는 변경되지 않아 유지보수 안정성이 확보됩니다.
주의해야 할 깊은 복사 문제
중첩된 객체 구조를 가진 설정을 다루는 경우 신중해야 합니다. Object.assign 은 1 차원까지만 복사하기 때문입니다.
const defaultTheme = {
palette: { bg: '#fff', text: '#000' }
};
const overrideTheme = {
palette: { font: 'sans-serif' }
};
const finalTheme = Object.assign({}, defaultTheme, overrideTheme);
// 예상치 못한 결과 발생
// finalTheme.palette 는 전체 객체가 교체되거나 일부만 합쳐지지 않을 수 있음
// 실제로는 overrideTheme 의 palette 객체 전체가 지정을 받으면 defaultTheme 의 색상이 사라질 위험이 있음
// 복잡한 구조는 로직 분산 또는 전용 라이브러리(Lodash 등) 권장
다른 방식과의 비교 분석
최근에는 전개 연산자 (Spread Syntax) 나 함수 파라미터 디스트럭처링을 통해 유사한 효과를 얻기도 합니다.
| 접근 방식 | 장점 | 고려 사항 |
|---|---|---|
| Object.assign | 여러 출처 명시적 병합 가능, 호환성 좋음 | 신호 처리 시 추가 검증 필요, 얕은 복사 주의 |
| 파라미터 디스트럭처링 | 코드 간결함, 개별 값 제어 용이 | 전체 객체 매칭보다는 단일 인수 처리에 적합 |
| 전개 연산자 ({...}) | 문법적 편의성 높음, 현대적 느낌 | 내부적으로는 assign 과 유사한 동작 수행 |