JavaScript 4.2
참조에 의한 객체 복사
-
객체와 원시 타입의 근본적인 차이 중 하나는 객체는 참조에 의해 저장되고 복사된다는 것이다.
-
원시값은 값 그대로 저장, 할당되고 복사된다.
-
객체의 동작 방식
-
변수엔 객체가 그대로 저장되는 것이 아니라, 객체가 저장되어 있는 메모리 주소인 객체에 대한 참조 값이 저장된다.
-
객체가 할당된 변수를 복사할 땐 객체의 참조 값이 복사되고 객체가 복사되지 않는다.
-
-
참조에 의한 비교
- 객체 비교 시 동등 연산자 == 와 일치 연산자 === 는 동일하게 동작한다.
- 비교 시 피연산자인 두 객체가 동일한 객체인 경우에 참을 반환한다.
-
객체 복사, 병합과 Object.assign
- 객체가 할당된 변수를 복사하면 동일한 객체에 대한 참조 값이 하나 더 만들어진다.
- 객체를 복사하고 싶다면? 기존에 있던 객체와 똑같으면서 독립적인 객체를 만들고 싶다면?
- 자바 스크립트는 객체 복제 내장 메서드를 지원하지 않는다.
- 참조에 의한 복사로 해결 가능한 일이 대다수이다.
- 정말 복제가 필요하다면 새로운 객체를 만든 다음 기존 객체의 프로퍼티들을 순회해 원시 수준까지 프로퍼티를 복사하면 된다.
let user = {
name: "John",
age: 30
};
let clone = {}; // 새로운 빈 객체
// 빈 객체에 user 프로퍼티 전부를 복사해 넣습니다.
for (let key in user) {
clone[key] = user[key];
}
// 이제 clone은 완전히 독립적인 복제본이 되었습니다.
clone.name = "Pete"; // clone의 데이터를 변경합니다.
alert( user.name ); // 기존 객체에는 여전히 John이 있습니다.
// Object.assign을 사용
Object.assign(dest, [src1, src2, src3...])
// 예시
let user = { name: "John" };
let permissions1 = { canView: true };
let permissions2 = { canEdit: true };
// permissions1과 permissions2의 프로퍼티를 user로 복사합니다.
Object.assign(user, permissions1, permissions2);
// now user = { name: "John", canView: true, canEdit: true }
// user에 동일한 이름을 가진 프로퍼티가 있는 경우 기존 값이 덮어씌워진다.
let user = { name: "John" };
Object.assign(user, { name: "Pete" });
alert(user.name); // user = { name: "Pete" }
// Object.assign을 사용하면 반복문 없이도 간단하게 객체를 복사할 수 있다.
let user = {
name: "John",
age: 30
};
let clone = Object.assign({}, user);
- 중첩 객체 복사
- 프로퍼티가 다른 객체에 대한 참조 값일 경우.
- 이런 경우 깊은 복사를 사용해야 한다.
- 값이 객체인 경우 객체의 구조도 복사해주는 반복문을 사용해야 한다.
- 표준 알고리즘인 Structured cloning algorithm을 사용하면 다양한 상황에서 객체를 복제할 수 있다.
- 자바스크립트 라이브러리 lodash의 메서드인 _.cloneDeep(obj)을 사용하면 이 알고리즘을 직접 구현하지 않고도 깊은 복사를 처리할 수 있다.