[JS] 얕은 복사와 깊은 복사

·2024년 3월 6일

Javascript

목록 보기
9/17

복사에는 두 종류가 있다.
이를 알기 위해서는 Call by Referecne를 알아야 한다.

얕은 복사

코드를 보자.

//Call By Value
let num =10
let copyNum=num;

num=10000;

console.log(copyNum);

결과로 뭐가 출력될까? 당연히 10이 출력된다.
그 이유는 number타입은 일반 자료형이고, 얘네는 원본 복사가 가능하다.

하지만 객체는 어떨까?

let it = {name :'it',age:42}; 
let copyIt = it;

it.name='new it';
console.log(this.name); // 'it'일까 'new it'일까?

출력결과는 놀랍게도 new it이다.
이상하다. copyIt 객체는 뭘 안건드린 것 같은데?

깊은 복사

객체(배열 포함) 데이터 타입은 레퍼런스 타입이다.
이들은 Call by Reference가 일어난다. 즉, 복사되는 객체는 기존 객체의 주소값을 참조하는 것 뿐이다.

let Person = function(age){this.age=age};
let p1 =new Person(10);
let p2 = p1;

p1.age=1000;

console.log(p2.age);//1000

하지만 나는 주소값 말고, 그냥 정말 객체의 원본값을 다 가져와버리고 싶다면?

이 때 이용하는 것이 '깊은 복사'다!!!

배열의 깊은 복사

반복문으로 값 할당하기

let nums=[1,2,3,4,5];
let deepNums =[];

nums.forEach(num)=>{deepNums.push(num)};

filter로 복사하기

객체의 모든 값을 복사하고 싶다면,항상 true를 반환하는 filter를 이용하자.

let deppNums2 = nums.filter((num)=>{true});

rest (...) 이용하기

let avengers = ['토르','스파이더맨','로키'];
let newAvengers = [...avengers,'로다주'];

assign 이용하기

//newObj 객체에 oldObj객체를 할당한 객체를 반환한다.
Object.assign(newObj,oldObj);

//빈 객체({})에 it 객체를 할당한 객체를 반환한다..
let deepIt = Object.assign({},it);

하지만 assign을 이용할 경우 내부 객체들은 얕은 복사가 된다.

객체의 비교

객체끼리 비교할 때에는, 내부의 데이터값을 비교하는 것이 아니라 주소값을 비교한다!

앞서 assign를 이용하여 깊은 복사를 진행했다. 그렇다면 다음 논리는 무엇이 나올까?

console.log(it == deepIt); //false
console.log(it === deepIt); //false

내부의 데이터 값은 같지만, 두 객체는 주소값이 다르므로, 내부 내용 상관 없이 모두 false가 뜬다.

이 말은, assign을 이용하면 객체 주소 자체는 달라도, 내부 프로퍼티들의 주소는 같게 된다는 말!

완벽하게, 내부 객체까지 완전히 참조를 분리시키는 법은 뭘까?
바로 JSON을 이용하는 것이다!!!

JSON의 깊은 복사

JSON.stringify(변수) - 문자열로 변환

let depIt = JSON.parse(JSON.stringify);

JSON.parse(변수) - 문자열을 객체로 변환

let depIt = JSON.parse(JSON.parse(it));
profile
풀스택 호소인

0개의 댓글