본문 바로가기

개발이나하자../frontend

[javascript] 객체 복사와 참조 차이| object deep copy | 객체 깊은 복사

값을 복사하고 싶을 때가 있다. 아래와 같은 상황을 말한다.

 

name 변수 안에 paige라는 값을 넣는다. clonedName이라는 변수에 name 값을 복사하고 싶다. 그러면 

위에 처럼 그냥 clonedName = name 하면 된다. clonedName과 name은 연결고리가 없다. 원시 값을 복사하기 때문에 문제가 되지 않는다.

숫자와 boolean 값도 마찬가지이다.

 

 

문제는 객체에서 나타난다.  배열로 예를 들어본다.

favouriteFruits 첫번째 값을 변경했을 뿐인데 fruits 값도 cherry로 바뀐다. 

fruits = favouriteFruits 라고 하는 것은 복사가 아니라 참조이기 때문이다. 

 

 

Ojbect에서도 배열과 같은 현상이 나타난다.

obj2 의 name 값을 jenny로 바꿨는데 obj.name 도 paige에서 jenny로 바뀐다.

 

 

이런 방법은 어떻게 해결해야 할까? 방법은 많다.

obj2라는 빈 object 를 만들고 값을 하나하나 넣는다. 이러면 원시 값을 넣는 것이기 때문에 복사가 된다.

그런데 만약에 오브젝트에 프로퍼니가 100개가 있을 때 이렇게 하나하나 값을 복사할 수 있나? 불가능하기 때문에 이 방법은 그렇게 좋은 방법은 아니다.

 

 

다른 방법을 보겠다.

Object.keys를 이용해서 key 값 배열을 만들고 forEach를 이용해 돌면서 새로운 obj 에 값을 넣는다.

위에 방법이랑 비슷한 방법이다.

 

 

여긴서 또 문제가 생긴다.

객체 안에 또 객체가 있을 경우에는 문제가 생긴다. 원시 값을 복사하는 게 아닌 객체를 다시 참조하기 때문이다.

 

 

객체와 객체가 참조하는지 확인하는 방법은 다음과 같다.

 

obj2 = obj 이렇게 하면 obj2 === obj 가 true라고 나온다. 참조하고 있다는 뜻이다. Object.keys()를 이용해서 obj3를 새로 만들었을 때는 

obj와 obj3은 false로 나온다.

 

 

그러면 더 쉽게 객체를 복사하는 법은 없을까 ?

 

JSON.parse(JSON.stringify(obj)) 를 사용하면 된다. 그런데 이것도 완전한 복사는 아니라고 함 ;;? 그리고 성능 저하가 심하다고 한다.

 

 

 

만약에 객체에 원시 값만 존재하는 경우 아래와 같은 방법을 사용해도 된다. 

 

obj.slice()를 사용하면 복사를 할 수 있다. 근데. slice()는 아래와 같은 역할을 한다.

 

그래서 배열 안에 object가 없고 원시 값만 있을 경우에 사용해야 한다.