JS의 얕은복사, 깊은 복사

이진우·2024년 1월 21일
0

코드잇 프론트엔드

목록 보기
6/11
post-thumbnail

JS의 얕은 복사와 깊은 복사에 대해 알아보자!

JS의 데이터 타입

복사를 이해하려면 데이터 타입을 이해해야 한다.

data type --|-- PrimitiveType-|-- Number
   			|				  |-- BigInt
			|				  |-- String
            |                 |-- Boolean
            |                 |-- null
            |                 |-- undefined
            |                 |-- Symbol
			|
            |-- Reference Type -- Object - |-- Array
           								   |-- Function
                                           |-- Date
                                           |-- RegExp
                                           |-- Map, WeakMap
                                           |-- Setm WeakSet

위 내용과 같이 데이터 타입은 크게 2가지로 나뉘게 된다.
기본형과 참조형이다.

모든 데이터들은 비트 단위로 저장되고
저장된 데이터들은 바이트 단위의 식별자
좀 더 자세하게 메모리 주솟값을 통해 서로 구분하고 연결할 수 있다.

기본형 변수 선언과 데이터 할당

var a;		// 변수 선언

a = 10;		// 데이터 할당

var a = 10;	// 변수 선언과 할당을 동시에!
주소(변수 영역)...1002100310041005...
데이터이름: a / 값: @5004
주소(데이터 영역)...5002500350045005...
데이터10

순서
1. 변수 영역에서 빈공간(@1003)을 확보한다
2. 확보한 공간의 식별자를 a로 지정한다.
3. 데이터영역의 빈 공간(@5004)에 문자열 'abc'를 저장한다.
4. 변수영역에서 a라는 식별자를 검색한다(@1003).
5. 앞서 저장한 문자열의 주소(@5004)를 @1003의 공간에 대입한다.

값이 변경이 변경 될 때

주소(변수 영역)...1002100310041005...
데이터이름: a / 값: @5005
주소(데이터 영역)...5002500350045005...
데이터'abc''change'

이렇게 기존의 값은 그대로 있고 새로운 공간에 값을 저장해 할당한다.

기본형 데이터는 모두 값이 변하지 않고 새로 생성해서 변경하기 때문에 불변 값이다.

참조형 변수 선언과 할당

var obj1 = {
	a: 1,
    b: 'bbb'
}
주소(변수 영역)...1002100310041005...
데이터이름: obj1 / 값: @5002
주소(데이터 영역)...5002500350045005...
데이터@7103~?1'bbb'
주소(객체의 변수 영역)71037104710571067107...
데이터이름: a / 값: @5004이름: b / 값: @5005

순서
1. 변수영역의 빈공간 확보 후 주소의 이름을 obj1로 지정
2. 임의의 데이터 저장공간(@5002)에 데이터를 저장하려고 보니 여러개의 프로퍼티로 이뤄진 데이터그룹임
이 그룹의 내부 프로퍼티들을 저장하기 위해 별도의 변수 영역을 마련하고 그 영역의 주소(@7103~?)를 @5002에 저장
3. @7103과 @7104에 각각 a와 b라는 프로퍼티 이름 지정
4. 데이터 영역에서 숫자 1을 검색, 현재 영역에 값이 없음으로 @5004를 할당, b도 동일한 과정을 거침

객체는 데이터 영역의 값이 바뀌지 않지만 할당된 값이 변경 가능하기 때문에 가변형

이러한 데이터의 할당 방식을 가지고 복사를 알아보자.

얕은 복사

얕은 복사는 객체를 복사할 때 기존값과 복사된 값이 같은 참조를 가리키고 있는 것을 말한다.

방식

  • Array.prototype.slice();

    • const copy = 복사하고싶은객체.slice(start, end);
    • 1차원 배열에서는 깊은 복사로 보이지만 2차원으로 들어가면 아님을 알 수 있다.
  • Object.assign(생성할 객체, 복사할 객체);

    • 복사하고싶은면 빈배열을 넣으면됨
    • const copy = Object.assign({},복사할 객체);
  • Spread 연산자 (전개 연산자)

    • const copy = {...복사할객체}

깊은 복사

깊은 복사는 원본 데이터에 영향을 미치지않게 참조가 끊어진 객체를 말한다.

방식

  • JSON.parse && JSON.stringify
    • 객체를 JSON으로 변환 시킨 후 다시 객체로 변환
    • 이 과정에서 객체가 function이면 undefined로 변환한다.
    • const copy = JSON.parse(JSON.stringify(object));
  • 재귀 함수를 구현한 복사
    • 복잡함
    function deepCopy(object) {
      if (object === null || typeof object !== "object") {
        return object;  
      }  
      // 객체인지 배열인지 판단  
      const copy = Array.isArray(object) ? [] : {};   
      for (let key of Object.keys(object)) {
        copy[key] = deepCopy(object[key]);
      }   
      return copy;
    } 
    const copy = deepCopy(object);
  • Lodash 라이브러리 사용
    • 편함
    • 코테에서는 사용 못 함
profile
츄라이츄라이

0개의 댓글