자바스크립트/CS

얕은 복사와 깊은 복사

길용쓰 2023. 7. 25. 08:33

숫자와 문자열, bool, NULL등 원시 타입 변수들은 기본적으로 깊은 복사가 된다.

a와 b는 완전히 다른 개체로 b의 값을 변경한다해도 a엔 영향을 주지 않는다

 

 

반면 배열이나 객체는 단순히 = 으로 값을 복사하면 얕은 복사가 되어

한 값을 수정하면 다른 값도 전부 수정된다.

이는 JS의 메모리 저장 방법과 연관이 있는데 자세한건 해당 글 참조

https://khs20010327.tistory.com/manage/posts/

 

Tistory

좀 아는 블로거들의 유용한 이야기

www.tistory.com

 

 

var arrCopy = arr.slice(); //ES5
let arrCopy = {...arr}; //ES6

var objCopy = Object.assign({}, obj); //ES5
let objCopy = {...obj}; //ES6

깊은복사를 하려면 배열의 경우엔 slice, 객체의 경우엔 Object.assign()이 있으며

ES6에선 산개 연산자로도 가능하다.

단 다차원 배열이나 오브젝트의 경우엔 1차원만 깊은 복사가 되므로 다른 방법을 사용해야한다.

 

const copiedObj = JSON.parse(JSON.stringify(originalObj));

const _ = require('lodash');
const clonedObj = _.cloneDeep(nestedObj);

let copiedObj = structuredClone(originalObj);

assign을 재귀적으로 적용하거나

 

객체를 문자열로 만들고(stringfy) 다시 객체화(parse) 시키거나

lodash를 import해 cloneDeep 함수를 쓰거나 여러 방법이 있었지만

이제 js가 기본적으로 제공하는 structuredClone()을 사용하면 된다 야호!

 

+

const target = { a: 1, b: 2 };
const source = { b: 4, c: 5 };

const merged = Object.assign(target, source);

console.log(target); // { a: 1, b: 4, c: 5 }
console.log(merged); // { a: 1, b: 4, c: 5 } (target과 동일한 객체)

// 새로운 객체를 만들고 싶을 때
const newMerged = Object.assign({}, target, source);

console.log(newMerged); // { a: 1, b: 4, c: 5 }

Object.assign은 첫번째 인자로 받은 target에

그 다음 인자 source들을 병합하는 메서드이다.

즉 target의 값이 변경되며

target에 빈 객체를 넣어 깊은 복사를 수행한 것이다.