두 객체 A와 B가 아래와 같이 있다고 가정해 보겠습니다.
const A = { activity: 'purchased', count: undefined, time: '09:05:33' };
const B = { activity: 'purchased', count: '51', time: undefined };여기서 요구사항은 이 두 객체를 병합하는 JavaScript 함수를 작성하는 것입니다. 중요한 조건은, 어떤 키가 참(truthy) 값을 가지고 있다면 그 값은 거짓(falsy) 값을 가진 키에 의해 덮어쓰여져서는 안 된다는 점입니다.
왜 스프레드 연산자만으로는 부족할까?
객체 병합에 흔히 사용되는 스프레드 연산자({ ...A, ...B })를 단순히 사용하면, 뒤에 오는 객체의 값이 앞선 객체의 값을 무조건 덮어쓰게 됩니다. 즉, 값이 undefined와 같은 거짓(falsy) 값인지 여부는 전혀 판단하지 않기 때문에 원하는 결과를 얻을 수 없습니다.
따라서 각 키의 값을 하나씩 검사하며 병합하는 반복적(iterative) 접근 방식을 사용해야 합니다.
구현 예제
다음은 위 요구사항을 만족하는 코드입니다.
const A = { activity: 'purchased', count: undefined, time: '09:05:33' };
const B = { activity: 'purchased', count: '51', time: undefined };
const mergeObject = (A, B) => {
let res = {};
Object.keys({ ...A, ...B }).map(key => {
res[key] = B[key] || A[key];
});
return res;
};
console.log(mergeObject(A, B));코드 동작 원리
Object.keys({ ...A, ...B })를 통해 두 객체의 모든 키를 한 번에 수집한 뒤, 각 키에 대해 B[key] || A[key]를 평가합니다. 논리 OR(||) 연산자는 왼쪽 값이 거짓(falsy)일 때만 오른쪽 값을 반환하므로, B의 값이 undefined처럼 유효하지 않으면 자동으로 A의 값이 사용됩니다.
실행 결과
위 코드를 실행하면 콘솔에 다음과 같은 출력이 나타납니다.
{ activity: 'purchased', count: '51', time: '09:05:33' }결과를 보면 count는 B의 유효한 값 '51'로, time은 A의 유효한 값 '09:05:33'으로 채워진 것을 확인할 수 있습니다. 이처럼 간단한 OR 연산 활용만으로도 undefined 같은 거짓 값을 자연스럽게 건너뛰며 두 객체를 안전하게 병합할 수 있습니다.