19. 참조에 의한 객체 복사
2026년 4월 10일
1. 참조에 의한 복사란? (Copy by Reference)
원시값(문자열, 숫자 등)은 값을 통째로 복사해서 독립적인 공간에 저장합니다. 반면, 객체는 **메모리상의 위치(주소)**만 복사합니다.
- 원시 타입: "사과"라는 물건을 직접 하나 더 만들어서 주는 것.
- 객체 타입: "사과가 들어있는 금고"의 열쇠를 하나 더 만들어서 주는 것.
예시: 한쪽을 수정하면 다른 쪽도 바뀐다
let user = { name: "John" }; let admin = user; // 열쇠(참조 값)만 복사됨 admin.name = "Pete"; // 열쇠로 금고를 열어 이름을 바꿈 console.log(user.name); // "Pete" (같은 금고를 보고 있기 때문)
2. 참조에 의한 비교
객체 비교 시 ==와 ===는 동일하게 동작합니다. **"두 객체의 내용이 같은가?"**가 아니라 **"두 변수가 같은 메모리 주소를 가리키는가?"**를 확인합니다.
- 참조가 같을 때:
a === b→true - 참조가 다를 때: 내용이 완전히 똑같은 빈 객체
{}와{}를 비교해도 결과는false입니다. 각각 다른 메모리 주소에 할당되었기 때문입니다.
3. 객체의 진짜 복제 방법 (Cloning)
참조가 아니라 진짜 독립된 복사본을 만들고 싶을 때는 다음과 같은 방법을 사용합니다.
① 얕은 복사 (Shallow Copy) - Object.assign
기존 객체의 프로퍼티들을 새로운 객체에 일일이 집어넣는 방식입니다.
let user = { name: "John", age: 30 }; let clone = Object.assign({}, user); // 빈 객체에 user의 내용을 복사
- 특징: 1단계 깊이의 프로퍼티들만 독립적으로 복사됩니다.
② 깊은 복사 (Deep Copy) - 중첩 객체 처리
객체 안에 또 다른 객체가 들어있는 경우, Object.assign을 써도 내부 객체는 여전히 참조로 연결됩니다. 이를 해결하려면 깊은 복사가 필요합니다.
structuredClone(obj): 최신 브라우저에서 지원하는 네이티브 깊은 복사 API입니다.- Lodash의
_.cloneDeep(obj): 실무 라이브러리를 활용한 가장 확실한 방법입니다.
🎙️ 기술 면접 대비 (Interview Questions)
Q1. 자바스크립트에서 객체 복사가 원시 타입과 다르게 동작하는 이유가 무엇인가요? (기초)
답변: 객체는 원시 타입에 비해 크기가 훨씬 크고 구조가 복잡할 수 있습니다. 이를 매번 값 전체를 복사하면 메모리 효율이 급격히 떨어지기 때문에, 효율적인 관리를 위해 실제 데이터는 메모리(Heap)에 저장하고 변수에는 그 주소(Reference)만 저장하여 전달하는 방식을 취합니다.
Q2. const a = {}; const b = {}; console.log(a === b); 의 결과와 그 이유는? (중급)
답변: 결과는
false입니다. 객체 리터럴{}을 작성할 때마다 메모리상에 새로운 객체가 생성됩니다.a와b는 각각 독립된 메모리 주소를 참조하고 있으므로, 참조 값을 비교하는 일치 연산자는false를 반환합니다.
Q3. Object.assign이나 전개 연산자(...)를 사용할 때의 한계점은 무엇인가요? (심화)
답변: 두 방법 모두 **'얕은 복사(Shallow Copy)'**를 수행합니다. 객체 내부에 또 다른 객체나 배열이 중첩되어 있는 경우, 가장 바깥쪽 객체만 새롭게 복사될 뿐 내부의 객체들은 여전히 원본과 같은 참조 주소를 공유합니다. 따라서 중첩된 객체를 수정하면 원본 데이터도 함께 변형되는 부작용이 발생할 수 있습니다.
Q4. 깊은 복사를 수행하는 가장 안전한 방법은 무엇인가요? (심화)
답변: 최근 모던 브라우저 환경이라면 네이티브 API인
structuredClone()을 사용하는 것이 가장 빠르고 안전합니다. 만약 더 복잡한 순환 참조나 특수한 객체 타입까지 고려해야 하는 레거시 환경이라면Lodash의cloneDeep같은 검증된 라이브러리를 사용하는 것이 좋습니다.