본문 바로가기
기술 개발/Javascript

얕은 복사 vs 깊은 복사

by 쪼짱 2023. 1. 12.
728x90
반응형
SMALL

자바스크립트에서의 얕은 복사와 깊은 복사를 알기 전,

자바스크립트의 데이터 타입에 대해 알아야 한다.

 

데이터 타입(Data Type)은 프로그래밍 언어에서 사용할 수 있는 데이터의 종류를 말한다.

데이터 타입은 데이터를 메모리에 저장할 때 확보해야 하는 메모리 공간의 크기와 할당할 수 있는 유효한 값에 대한 정보, 그리고 메모리에 저장되어 있는 2진수 데이터를 어떻게 해석할 지에 대한 정보를 컴퓨터와 개발자에게 제공한다.

 

자바스크립트에서 데이터 타입은 원시 타입객체 타입으로 나뉜다.

원시 타입의 값은 변경 불가능한 값(immutable value)이며 pass-by-value(값에 의한 전달) 방식으로 전달된다.

객체 타입의 값은 pass-by-reference(참조에 의한 전달) 방식으로 전달된다.

원시 타입(Primitive data type)

  • boolean
  • null
  • undefined
  • string
  • number
  • symbol(ES6)

객체 타입(Object/reference type)

  • object(array, function...)

 

원시 타입은 값을 복사할 때, 복사된 값을 다른 독립적인 메모리에 할당하기 때문에 복사를 하고 값을 수정한다고 해도, 원래의 값과 복사된 값이 서로에게 영향을 미치지 않는다. 이렇게 실제 값을 복사하는 것을 깊은 복사라고 한다.

let a = 1;
let b = a;
b = 2;

console.log(b) // 2

 

하지만, 객체/참조 타입은 변수가 객체의 주소를 가리키는 값이기 때문에 복사된 값(주소)이 같은 값을 가리키기 때문에 복사된 변수 또한 객체가 저장된 메모리 공간의 참조를 가리키고 있다. 그래서 복사를 하고 객체를 수정하게 되면, 변수는 똑같은 참조를 가리키고 있기 때문에 기존 객체를 저장한 변수에 영향을 끼친다. 이렇게 객체의 참조값(주소값)을 복사하는 것을 얕은 복사라고 한다.

let apple = {
	name: 'apple'
}
let orange = apple;
orange.name = 'orange'

console.log(apple);		// { name: 'orange' }
console.log(orange);	// { name: 'orange' }

 

 

얕은 복사와 깊은 복사

1. 얕은 복사(Shallow copy)

얕은 복사는 참조 주소를 공유한다. 즉, 객체의 참조값(주소 값)을 복사한다.

객체를 복사할 때 원래 값과 복사된 값이 같은 참조를 가리키고 있는 것을 말하며,

객체 안에 객체가 있을 경우 한 개의 객체라도 원본 객체를 참조하고 있는 것을 말한다.

  1. Array.prototype.slice(), concat()
    • 처음부터 마지막 인덱스까지 기존 배열에서 추출해 새로운 배열을 리턴하는 메소드
    • 여기서, 처음과 마지막을 설정하지 않으면 기존 배열을 전체 얕은 복사를 한다.
    • 1차원 배열에서는 깊은 복사가 허용이 되지만 2차원  이상부터는 깊은 복사가 되지 않고 얕은 복사가 된다. 
  2. Object.assign(생성할 객체, 복사할 객체)
    • 첫번째 요소로 들어온 객체에 다음인자로 들어온 객체를 복사해준다.
    • 메소드의 첫번째 인자로 빈 객체를 넣고, 두번째 인자로 복사할 객체를 넣어준다.
  3. Spread 연산자 (전개 연산자)

 

2. 깊은 복사(Deep copy)

깊은 복사는 참조 주소를 공유하지 않고 참조 공간도 복사한다. 즉, 객체의 실제 값을 복사한다.

객체 안에 객체가 있을 경우에도 원본과의 참조가 완전히 끊어진 객체를 말한다.

  1. 재귀 함수를 이용한 복사
    • 복잡하다는 단점이 있음
  2. JSON 사용
    • JSON.stringify() - 객체를 json 문자열로 변환하면, 원본 객체와의 참조가 모두 끊어짐
    • JSON.parse() - 객체를 json 문자열로 변환 후, 다시 자바스크립트 객체로 만들어 줌
    • 간단하고 사용하기 쉽지만, 다른 방법들에 비해 느리고, 객체가 function일 경우 undefined로 처리한다는 단점이 있다.
  3. lodash 라이브러리의 cloneDeep() 사용
    • 더 쉽고 안전하게 복사를 할 수 있지만, 라이브러리를 설치해야한다는 점과 일반적인 개발과는 달리 코딩 테스트에는 사용할 수 없다는 단점이 있다.

 


참고

https://developer.mozilla.org/ko/docs/Web/JavaScript/Data_structures

https://poiemaweb.com/js-data-type-variable

https://bbangson.tistory.com/78

https://developer-talk.tistory.com/86

https://velog.io/@th0566/Javascript-%EC%96%95%EC%9D%80-%EB%B3%B5%EC%82%AC-%EA%B9%8A%EC%9D%80-%EB%B3%B5%EC%82%AC

https://ko.javascript.info/object-copy

 

728x90
반응형
LIST

'기술 개발 > Javascript' 카테고리의 다른 글

parameter와 argument의 차이  (0) 2023.03.28
정규표현식(Regex)  (0) 2023.02.08
호이스팅(Hoisting) (feat. var, let, const)  (0) 2023.01.05
async & await  (0) 2022.08.10
Promise (then, catch)  (0) 2022.08.09