참조에 의한 객체 복사
📢 객체는 참조에 의해(by reference) 저장되고 복사된다.
◾️ 변수엔 객체가 그대로 저장되는 것이 아니라, 객체가 저장 되어 있는 '메모리 주소'인 객체에 대한 '참조 값'이 저장된다.
◾️ 객체는 메모리 내 어딘가에 저장되고, 변수에는 객체를 '참조❗️'할 수 있는 값이 저장된다.
◾️ 객체가 할당된 변수를 복사할 땐 객체의 참조 값만 복사되고 객체는 복사되지 않는다.
◾️ 변수는 두 개 이지만 각 변수엔 동일 객체에 대한 참조값이 저장된다.
let user = { name: "suzu" };
let admin = user;
admin.name = 'ruru';
console.log(user.name); // ruru
참조에 의한 비교
📢 객체 비교 시 피연산자인 두 객체가 동일 객체인 경우에는 참을 반환한다.
let a = {};
let b = a; // 참조에 의한 복사
console.log( a == b ); // true
console.log( a === b ); // true
◾️ 겉 보기에는 객체 a,b가 같아보이지만, 독립된 객체이기 때문에 거짓을 반환한다.
let a = {};
let b = {};
console.log( a == b ); // false
◾️ obj1 > obj2 같은 대소 비교나 obj == 5 같은 원시값과의 비교에선 객체가 원시형으로 변환된다.
객체 복사, 병합과 Object.assign
◾️ 자바스크립트는 객체 복제 내장 메서드를 지원하지 않는다.
◾️ 방법 1 : 새로운 객체를 만든 다음 기존 객체의 프로퍼티들을 순회해 원시 수준까지 프로퍼티를 복사하면 된다.
let user = { name: 'suzu', age: 30 };
let clone = {};
for (let key in user) {
clone[key] = user[key];
}
clone.name = 'ruru'
console.log(clone); // { name: 'ruru', age: 30 }
console.log(user.name); // suzu
◾️ 방법 2 : Object.assign
Object.assign(dest, [src1, src2, src3...])
◾️ dest : 목표로 하는 객체
◾️ src1, ..., srcN : 복사하고자 하는 객체(여러개 사용 가능)
◾️ 객체 src1, ..., srcN의 프로퍼티를 dest에 복사한다. dest를 제외한 객체의 프로퍼티 전부가 첫 번째 객체로 복사된다.
◾️ dest를 반환한다.
◾️ dest에 동일한 이름을 가진 프로퍼티가 있는 경우엔 기존 값이 덮어 씌워진다.
let user = { name: "suzu" };
let userInfo1 = { age: 30 };
let userInfo2 = { role: 'admin' };
let userInfo3 = { name: 'ruru' };
Object.assign(user, userInfo1, userInfo2, userInfo3);
console.log(user)// { name: 'ruru', age: 30, role: 'admin' }
◾️ 방법 1을 Object.assign을 사용하면 반복문 없이도 간단하게 객체를 복사할 수 있다.
let user = { name: 'suzu', age: 30 };
let clone = Object.assign({}, user);
console.log(clone); // { name: 'suzu', age: 30 }
중첩 객체 복사
◾️ 프로퍼티는 다른 객체에 대한 참조 값일 수도 있다.
◾️ Object.assign을 사용해도 clone.size는 독립된 객체가 아닌 참조 값이 복사된다.
let user = {
name: "suzu",
sizes: {
height: 160,
width: 50
}
};
let clone = Object.assign({}, user);
console.log( user.sizes === clone.sizes ); // true
user.sizes.width++;
console.log(clone.sizes.width); // 51
얕은 복사(shallow copy)
◾️ 가장 상위 객체만 새로 생성되고 내부 객체들은 참조 관계인 경우
깊은 복사(deep cloning)
◾️ user[key]의 각 값을 검사하면서, 그 값이 객체인 경우 객체의 구조도 복사해주는 반복문을 사용해야 한다.
function deepCopyObject(obj) {
let clone = {};
for(var i in obj) {
if(typeof(obj[i])=="object" && obj[i] != null)
clone[i] = deepCopyObject(obj[i]);
else
clone[i] = obj[i];
}
return clone;
}
let user = {
name: "suzu",
sizes: {
height: 162,
width: 50
}
};
let result = deepCopyObject(user);
result.sizes.height = 150;
console.log(result.sizes.height); // 150;
console.log(user.sizes.height); // 162
◾️ Structured cloning algorithm : 깊은 복사 시 사용되는 표준 알고리즘
◾️ 자바스크립트 라이브러리 lodash의 메서드인 _.cloneDeep(obj)를 사용
📝 오늘 새롭게 배운 내용 📝
✅ 객체의 복사
: 312호 방에 들어가기 위해 열쇠(key1)를 복사(key2)한 것과 같다.
key1과 key2의 이름은 다르지만 같은 방에 들어 갈 수 있다.
✅ Object.assign
✅ 얕은 복사, 깊은 복사
📌 [JAVASCRIPT_INFO 참조에 의한 객체 복사]
📌 [MDN Object.assign]
'모던 자바스크립트' 카테고리의 다른 글
4.5 'new' 연산자와 생성자 함수 (0) | 2020.08.10 |
---|---|
4.4 메서드와 'this' (0) | 2020.08.08 |
4.3 가비지 컬렉션 (0) | 2020.08.06 |
4.1 객체 - 객체 (0) | 2020.08.04 |
모던 JavaScript 정독하기 (0) | 2020.08.04 |