
자바스크립트에서 객체와 원시 타입은 저장 및 복사 방식이 다르다. 원시값은 값 그대로 복사되지만, 객체는 ‘참조에 의해(by reference)’ 저장 및 복사된다. 이 글에서는 참조에 의한 객체 복사와 객체 비교, 복제 방법을 알아본다.
원시값(문자열, 숫자, 불린 값)은 값 그대로 저장 및 복사된다.
let message = "Hello!";
let phrase = message;
위 코드를 실행하면 message와 phrase는 각각 독립적인 값을 가지게 된다.
객체는 메모리 어딘가에 저장되고, 변수에는 객체의 참조값(메모리 주소)이 저장된다.
let user = {
name: "John"
};
변수 user는 객체가 아닌 객체를 참조하는 값을 저장한다.
객체를 다른 변수에 복사하면 객체 자체가 아닌 참조값이 복사된다.
let admin = user; // 참조값 복사
두 변수는 동일한 객체를 참조하므로, 한 변수를 통해 객체를 수정하면 다른 변수에서도 변경 사항을 확인할 수 있다.
admin.name = 'Pete';
console.log(user.name); // 'Pete'
==와 === 연산자는 동일하게 동작하며, 두 변수가 동일한 객체를 참조할 때 참을 반환한다.
let a = {};
let b = a;
console.log(a == b); // true
console.log(a === b); // true
서로 다른 객체는 내용이 같아도 참조가 다르므로 동등/일치 비교 시 거짓이 반환된다.
let a = {};
let b = {};
console.log(a == b); // false
객체를 복제하려면 프로퍼티를 순회하며 복사해야 한다.
let user = { name: "John", age: 30 };
let clone = {};
for (let key in user) {
clone[key] = user[key];
}
console.log(clone); // { name: "John", age: 30 }
Object.assign으로 복사Object.assign 메서드를 사용하면 반복문 없이 객체를 복사할 수 있다.
let user = { name: "John" };
let clone = Object.assign({}, user);
console.log(clone); // { name: "John" }
Object.assign을 사용해 여러 객체를 병합할 수도 있다.
let user = { name: "John" };
let permissions1 = { canView: true };
let permissions2 = { canEdit: true };
Object.assign(user, permissions1, permissions2);
console.log(user); // { name: "John", canView: true, canEdit: true }
객체의 프로퍼티가 또 다른 객체를 참조하는 경우, 얕은 복사는 참조만 복사한다.
let user = {
name: "John",
sizes: { height: 182, width: 50 }
};
let clone = Object.assign({}, user);
console.log(user.sizes === clone.sizes); // true
위 코드는 user.sizes와 clone.sizes가 동일한 객체를 참조하므로 문제가 될 수 있다.
깊은 복사는 중첩된 객체까지 복사하는 것을 의미한다. 이를 구현하려면 추가적인 코드가 필요하며, 일반적으로 Lodash의 _.cloneDeep과 같은 라이브러리를 사용한다.
Object.assign은 1단계 깊이의 프로퍼티를 복사한다.