JS 참조형 데이터 타입

코곰·2022년 11월 3일
1

#이 내용은 코어자바스크립트(by. 정재남)의 강의내용과 책을 정리한 내용입니다.

원래 목표는 매일 공부하고 블로그를 쓰는 것이었지만.. 단 하루만에 실패할 줄은 정말 몰랐다.. 이제라도 열심히 적을 예정이다!!


  1. 참조형 data type

    앞서 말했듯 참조형 데이터 타입에는 Object(Array, Function, Date, RegExp, Map/WeakMap, Set/WeakSet)이 있다.

    기본형은 주솟값을 바로 복제하는 반면
    참조형은 값이 담긴 주솟값들로 이루어진 묶음을 가리키는 주솟값을 복제
    한다는 점이 다르다.

    아래에서 이 말이 무엇을 의미하는지 알아보자.

  2. 변수와 참조형 data type은 어떻게 메모리에 저장될까?

    	이전 글과 같이 실제 메모리 구조는 복잡하지만 이해를 위해 책에서 사용한 것과 비슷하게 간략하게 표현합니다.
    var obj1 = {
      	a : 10,
      	b : [10,20]
    };
    1. 우선 변수 영역에 빈 공간을 확보하고 식별자를 'obj1'으로 설정한다.

      이해를 돕기 위해 @1002~ 는 변수영역, @3002~ 는 데이터 영역, @5002~ 는 obj1 의 프로퍼티 영역, @7002~ 는 obj1의 b의 프로퍼티 영역입니다.

      주소...1002100310041005...
      데이터식별자 : obj1
      값 :

      주소...3002300330043005...
      데이터

      주소...5002500350045005...
      데이터

      주소...7002700370047005...
      데이터

    2. 데이터가 여러 개이다 보니 이들을 저장하기 위한 별도의 영역(@5002~)을 마련하고 이 영역의 주소를 @3002에 저장하고 @1002의 값에 @3002 주소를 저장한다.

      주소...1002100310041005...
      데이터식별자 : obj1
      값 : @3002

      주소...3002300330043005...
      데이터@5002 ~

      주소...5002500350045005...
      데이터

      주소...7002700370047005...
      데이터

    3. 객체 obj1.a의 값인 10을 데이터영역에서 검색 후 없으니 추가합니다. 이후 @5002의 식별자를 a로 설정하고 값은 10을 저장한 @3003을 저장합니다.

      주소...1002100310041005...
      데이터식별자 : obj1
      값 : @3002

      주소...3002300330043005...
      데이터@5002 ~10

      주소...5002500350045005...
      데이터식별자 : a
      값 : @3003

      주소...7002700370047005...
      데이터

    4. 객체 obj.b의 값을 저장하려 보니 프로퍼티가 여러개이니 앞서 2번 단계처럼 이를 위한 별도의 영역(@7002~)을 마련합니다. 이후 이 주소를 데이터 영역(@3004)에 저장합니다. @5003에는 식별자 b, 값은 앞서 저장한 @3004를 저장합니다.

      주소...1002100310041005...
      데이터식별자 : obj1
      값 : @3002

      주소...3002300330043005...
      데이터@5002 ~10@7002 ~

      주소...5002500350045005...
      데이터식별자 : a
      값 : @3003
      식별자 : b
      값 : @3004

      주소...7002700370047005...
      데이터

    5. obj.b의 각 프로퍼티 들의 값을 데이터 영역에 저장하고 @7002 ~ 의 영역에 식별자와 함께 저장합니다.

      주소...1002100310041005...
      데이터식별자 : obj1
      값 : @3002

      주소...3002300330043005...
      데이터@5002 ~10@7002 ~20

      주소...5002500350045005...
      데이터식별자 : a
      값 : @3003
      식별자 : b
      값 : @3004

      주소...7002700370047005...
      데이터식별자 : 0
      값 : @3003
      식별자 : 1
      값 : @3005

      여기서 obj1.a와 obj1.b[0]의 값은 둘 다 같은 10입니다. 위에 간략하게 표현한 메모 상에서도 같은 @3003을 가리키고 있습니다.

      만약 같은 값이라고 한다면 데이터 영역에 새로 추가하지 않고 있는 것을 사용한다는 것을 알 수 있습니다. 즉 데이터를 추가할 때 데이터 영역에 해당하는 값이 있는지 검색하는 과정이 필요합니다.

      언뜻 보면 비효율적이라고 생각할 수 있지만 메모리의 수명과 용량 등등을 고려하면 새로 저장할 때에는 비효율적일 수 있지만 이득이 훨씬 크다는 것을 알 수 있습니다.

  3. 그럼 추후에 값을 변경할 때는 어떻게 될까?

    단순히 값을 변경하는 경우는 이전 글인 기본형 data type이 변하는 과정과 비슷하다. 다만 가장 큰 차이점이 있다.

    var obj1 = {
      a : 10,
      b : [10,20]
    };
    
    obj1.a = 20;
    obj1.b = 10;
    obj1.a = 20;

    이 부분부터 보면

    1. 데이터 영역에 20이 있으므로 obj1.a(@5002)의 값을 @3005로 바꿔주면 끝난다.

      주소...1002100310041005...
      데이터식별자 : obj1
      값 : @3002

      주소...3002300330043005...
      데이터@5002 ~10@7002 ~20

      주소...5002500350045005...
      데이터식별자 : a
      값 : @3005
      식별자 : b
      값 : @3004

      주소...7002700370047005...
      데이터식별자 : 0
      값 : @3003
      식별자 : 1
      값 : @3005

    2. 그럼 그 다음 부분은?

    obj1.b = 10;

    obj1.b(@5003)의 값을 @3003으로 저장해주면 된다.

    주소...1002100310041005...
    데이터식별자 : obj1
    값 : @3002

    주소...3002300330043005...
    데이터@5002 ~10@7002 ~20

    주소...5002500350045005...
    데이터식별자 : a
    값 : @3005
    식별자 : b
    값 : @3003

    주소...7002700370047005...
    데이터식별자 : 0
    값 : @3003
    식별자 : 1
    값 : @3005

    이 경우 @3004를 참조하는 것은 아무것도 없다. 즉 참조 카운트가 0이 되고 @3004가 참조하는 @7002 ~ 또한 참조 카운트가 0이 된다. 이는 나중에 GC(garbage collector)의 대상이 된다.

profile
입니다.

0개의 댓글