-
참조 타입
- 변수에 실제 값을 저장하지 않고 실제 값이 저장된 메모리 주소를 참조
- 객체가 할당된 변수를 복사하거나 함수의 인자로 넘길 땐 객체가 아닌 객체의 참조가 복사됨.
- 객체, 배열, 함수, 날짜
-
원시 타입
- 변수에 값 자체 저장
- 숫자, 문자열, 불리언, null, undefined
-
원시 타입 값들을 가진 일반 객체를 얕은 복사할 경우
객체 내의 원시 타입 값들은 값 복사가 되고, 서로 다른 메모리 주소를 가르키기 때문에 문제되지 않음. -
중첩 객체를 얕은 복사할 경우
내부 객체를 복사할 때 참조 값을 복사하기 때문에 원본 객체와 복사 객체가 같은 참조를 가지게 되고
객체 속성 값을 변경할 경우 해당 값을 참조하는 다른 객체에도 영향을 미치게 되는 문제 발생.→ 즉, 참조 타입의 경우 값이 객체의 주소를 참조하고 있기 때문에
얕은 복사를 수행하면 주소 값만 복사되어 원본 객체와 복사 객체가 같은 객체를 참조하는 문제 발생.
-
깊은 복사는 객체에 중첩되어 있는 객체까지 모두 실제 값을 복사해 원시 값처럼 완전한 복사본을 만듦
-
별개의 메모리 주소를 참조하기 때문에 서로 독립적인 객체임
→ 원본을 보존할 필요가 있을 경우 깊은 복사를 사용하는 것이 좋음
let obj = { a: 1, b: 2, c: 3 };
let clone = { ...obj }
let obj = { a: 1, b: 2, c: 3 };
let clone = Object.assign({}, obj);
let arr = [1,2,3];
let clone = arr.slice();
let arr = [1,2,3];
let clone = [].concat(arr);
let user = {
name: "John",
sizes: {
height: 182,
weight: 50
}
};
let clone = Object.assign({}, user);
alert( user.sizes === clone.sizes ); // true
user.sizes.width = 79;
alert(clone.sizes.width); // 79
let clone = {...user, sizes: {...user.sizes}};
let clone = Object.assign({}, user, {sizes: Object.assign({}, user.sizes)});
- 위 두가지 방법은 복사해야하는 속성을 하나씩 지정해야 하므로 불편할 수 있음.
let clone = JSON.parse(JSON.stringify(user));
- 객체가 JSON으로 직렬화(serialization)되어 문자열로 변환되기 때문에, 함수나 심볼같은 특별한 타입의 속성은 포함되지 않음.
- 객체의 속성 값 중에 순환 참조(circular reference)가 있는 경우 동작하지 않음.
- 객체의 크기가 크다면 JSON 문자열을 만들기 위해 메모리를 많이 사용할 수 있음.
// Object.assign()과 재귀함수 이용하여 중첩 객체 값 복사하기
function deepCopyWithAssign(obj) {
let newObj = Object.assign({}, obj);
for (let key in newObj) {
if (typeof newObj[key] === 'object' && newObj[key] !== null) {
newObj[key] = deepCopyWithAssign(newObj[key]);
}
}
return newObj;
}
let clone = deepCopyWithAssign(user);
// 재귀함수 이용하여 중첩 객체 값 복사하기
function deepCopy(obj) {
let result = {};
for (let key in obj) {
if (typeof obj[key] === "object" && obj[key] !== null) {
result[key] = deepCopy(obj[key]); // 객체면 재귀적으로 복사
} else {
result[key] = obj[key]; // 객체 아니면 값 복사
}
}
return result;
}
let clone2 = deepCopy(user);
// null도 객체 타입으로 인식하기 때문에 obj[key] !== null 추가
모던 자바스크립트 튜토리얼
자바스크립트 딥다이브