1차원 객체일 때는 깊은 복사가 되는 방법들이 2차원 이상부터 내부객체에 대하여 깊은복사가 이루어지지 않을 때 해결하는 방법
얕은 복사 (Shallow copy)란?
- 주소 값을 복사하기 때문에 참조하고 있는 실제 값이 같아 원본과 복사본이 서로 영향을 받는다.
깊은 복사 (Deep copy)란?
- 실제 값을 독립적인 새로운 메모리 공간에 복사, 참조를 공유하지 않아 원본과 복사본이 서로 영향을 받지 않는다.
2023.02.16 - [개발 용어 정리] - [개발용어] 얕은 복사(Shallow Copy)와 깊은 복사(Deep Copy)
[개발용어] 얕은 복사(Shallow Copy)와 깊은 복사(Deep Copy)
얕은 복사(Shallow Copy)와 깊은 복사(Deep Copy) A = 원본 B = 복사하려는 객체 얕은 복사 새로운 B객체를 생성 후 원본 A객체를 메모리 영역을 참조해서 원본에 종속된 객체를 생성하는 것이 얕은 복사
kfdd6630.tistory.com
2차원 이상의 객체 얕은 복사가 되는 경우
* 아래 두 가지 얕은 복사 방식의 경우 1차원 객체일 때에는 깊은 복사가 된다.
방법 1. Object.assign()
const original = {
a: 1,
b: {
c: 2,
}
}
const clone = Object.assign({}, original);
// clone(복사본)의 값을 변경했을 때
clone.b.c = 3;
console.log(original === clone); // false 출력
console.log(original.b.c); // 3 출력
console.log(original.b.c === clone.b.c); // true 출력
방법 2. 스프레드 연산자(...)
const original = {
a: 1,
b: {
c: 2,
}
}
const clone = {...obj};
clone.b.c = 3;
console.log(original === clone); // false 출력
console.log(original.b.c); // 3 출력
console.log(original.b.c === newObj.b.c); // true 출력
- 위 두 방법 모두 original과 clone이 다른 것으로 보아 두 객체는 다른 참조 값을 갖는다.
- 따라서 clone의 c의 값을 변경했을 때, obj의 c 값은 변화가 없어야 하지만 obj의 c 값도 3으로 변경되었다.
- 이러한 현상이 일어나는 이유는 2차원 이상의 객체일 때 내부 객체는 깊은 복사가 되지 않기 때문이다.
2차원 이상의 객체 깊은 복사하기
방법 1. JSON.parse() + JSON.stringify()
const original = {
a: 1,
b: {
c: 2,
}
}
const clone = JSON.parse(JSON.stringify(original))
clone.b.c = 3;
console.log(original === clone); // false 출력
console.log(original.b.c); // 2 출력
console.log(original.b.c === clone.b.c); // false 출력
JSON.stringify() 메서드를 통해 String 타입으로 변환 후, JSON.parse() 메서드로 다시 객체로 변환해준다.
이 과정에서 두 객체의 참조 관계는 완전히 끊기게 되어 깊은 복사가 된다.
2023.04.26 - [언어/Javascript,TypeScript] - [js] JSON관련 메소드(JSON.stringify(), JSON.parse())
[js] JSON관련 메소드(JSON.stringify(), JSON.parse())
JSON - 메소드 네트워크를 통해 객체를 어딘가에 보내거나 로깅 목적으로 객체를 출력해야 한다면 객체를 문자열로 전환해야 한다. 전환된 문자열엔 원하는 정보가 있는 객체 프로퍼티 모두가 포
kfdd6630.tistory.com
방법 2. 재귀 함수
const deepCopy = (obj) => {
if (obj === null || typeof obj !== "object") {
return obj;
}
let copy = {};
for (let key in obj) {
copy[key] = deepCopy(obj[key]);
}
return copy;
}
const original = {
a: 1,
b: {
c: 2,
},
func: function () {
return this.a;
},
};
const clone = deepCopy(original);
clone.b.c = 3;
console.log(original === clone); // false 출력
console.log(original.b.c); // 2 출력
console.log(original.b.c === clone.b.c); // false 출력
재귀 함수를 사용하여 2차원 이상의 객체일 때 내부 객체까지 깊은 복사를 하여 반환한다.
방법 3. lodash & cloneDeep()
const L = require('lodash');
const original = {
a: 1,
b: {
c: 2,
},
};
const clone = L.cloneDeep(original);
clone.b.c = 3;
console.log(original === clone); // false 출력
console.log(original.b.c); // 2 출력
console.log(original.b.c === clone.b.c); // false 출력
이 방법은 ladash 라이브러리를 설치해서 사용해야 한다.
방법 4. ramda & clone()
const R = require('ramda');
const original = {
a: 1,
b: {
c: 2,
},
};
const clone = R.clone(original);
clone.b.c = 3;
console.log(original === clone); // false 출력
console.log(original.b.c); // 2 출력
console.log(original.b.c === clone.b.c); // false 출력
이 방법은 ramda 라이브러리를 설치해서 사용해야 한다.
'언어 > Javascript, Typescript' 카테고리의 다른 글
[js, ts] number타입 전화번호 배열 string타입으로 바꾸기(' - '삽입) (0) | 2023.05.02 |
---|---|
[js] e.preventDefault(), e.stopPropagation(), e.stopImmediatePropagation() (0) | 2023.04.28 |
[js, Next.js] <input> 한글 입력 후 엔터 시 중복 이벤트 발생 문제 (0) | 2023.04.27 |
[js] JSON관련 메소드(JSON.stringify(), JSON.parse()) (0) | 2023.04.26 |
[js] 배열 합치기(concat(), spread 연산자, push()) (0) | 2023.04.25 |
댓글