데이터 타입

holang-i·2021년 8월 2일
0
post-thumbnail
post-custom-banner

Javascript 핵심 개념 알아보기 - JS Flow 를 공부하며 정리합니다.

ES6 이전까지의 자바스크립트의 전반적인 흐름을 공부합니다.

자바스크립트의 두 개의 데이터 타입의 차이점과 그 차이가 발생하는 원인에 대해서 살펴 볼 것이다.

Primitive Type 기본형

  • Number
  • String
  • Boolean
  • null
  • undefined
  • Symbol (ES6)

Reference Type 참조형

Object

  • Array
  • Function
  • RegExp (정규 표현식)

위의 두 가지 데이터 타입을 구별해야되는 이유를 메모리를 살펴보면서 공부해 볼 것이다.


기본형 타입의 메모리 흐름

let a;

a라는 변수를 선언하면 메모리 안에 데이터가 담길 공간을 미리 확보한다. 1003번에 이름, 값의 위치를 잡아놓는다.

확보한 공간의 이름을 식별자 'a'로 지정을 한다.

주소...1002100310041005...
데이터이름: a

a = 'abc';

이후 'abc'라는 문자열을 할당하라는 명령어를 넣으면 우선 문자열 'abc'를 메모리의 다른 빈 공간에 넣는다.

그리고 그 메모리에 있는 주솟값 5004번을 들고, 식별자 'a'가 있는 1003번으로 가서 1003의 값에 @5004을 넣는다.

주소...1002100310041005...
데이터이름: a
값: @5004

주소...5002500350045005...
데이터'abc'

a = 'qwert';

이후 다시 'qwert'라는 문자열을 재할당면 또 임의의 공간인 5005에다 미리 확보를 한 뒤 저장을 하고, 식별자 'a'가 위치한 1003번으로 가서 값을 @5004번 대신 @5005으로 덮어 씌우기를 한다.

주소...1002100310041005...
데이터이름: a
값: @5005

주소...5002500350045005...
데이터'abc''qwert'

참조형 타입의 메모리 흐름

let obj = {
  a: 1,
  b: 'bbb',
};

우선 obj를 선언하는 과정이 먼저니까 1002번에 공간을 확보해서 식별자 이름을 obj로 넣는다.

주소...1002100310041005...
데이터이름: obj

그다음에는 할당을 해야되는데 할당을 하려고 보니까 (중간에 다른 데이터들 처리..) 5002번에 공간을 확보해놨는데 5002번 안에다 데이터를 통으로 넣을 수 있을까? 생각해봤는데 메모리 구조 공간상 들어갈 수 있는 데이터 구조가 1개씩밖에 안 들어간다.

어 그러면 여러개를 넣어놓고, 그 여러개를 묶음 처리해서 그 주소를 넣어야겠다!

주소...5002500350045005...
데이터@7103 ~ ?

7103번 이후부터 어디까지인지는 모르겠지만 공간을 많이 확보해놓고, 거기에 들어가있는 데이터들은 전부 이 객체야 —> 라고 만들어 놓고 7103 ~ 부터 데이터들을 하나 씩 넣을것이다.

주소...7103710471057106...
데이터

a: 1,

a라는 property에 1을 넣으라고 했으니까 a를 넣는 공간을 확보하고 1을 넣는 과정을 다른 빈 데이터에 넣어서 주소를 값에 넣는다.

b: 'bbb'

b도 a와 마찬가지로 넣는 공간을 확보하고 'bbb'를 넣는 과정을 다른 빈 데이터에 넣어서 주소를 값에 넣는다.


주소...1002100310041005...
데이터이름: obj
값: @5002

주소...5002500350045005...
데이터@7103 ~ ?1'bbb'

주소...7103710471057106...
데이터이름: a
값: @5003
이름: b
값: @5004

그렇게해서 객체 안에 있는 내용들에 할당이 다 끝나면 그제서야 7103부터 이후에 있는 개체들이 담겨 있는 주소를 가리키고 있는 5002번에 있는 주소를 obj에 넣게 된다.


📣  참조형 타입은 한 단계를 더 거쳐가는 형태가 된다.


obj.a = 2;

이번에는 a라는 property의 값을 2로 바꾸는것을 생각해 볼 것이다.


주소...1002100310041005...
데이터이름: obj
값: @5002

주소...5002500350045005...
데이터@7103 ~ ?1'bbb'

주소...7103710471057106...
데이터이름: a
값: @5003
이름: b
값: @5004
  1. 일단 obj를 찾으면 obj를 가리키고 있는 1002번을 찾아간다.
  2. 1002번이 가리키고 있는 5002번으로 간다.
  3. 5002번을 가보니까 @7103 ~ 를 가리키고 있어서 다시 가리키는 곳으로 간다.
  4. 먼저 a property를 찾는다!
  5. a property를 가리키고 있는 것을 찾으면 7103이다.
  6. 7103에 있는 값을 2로 대체해라 했을 때 2를 할당해야 되기 때문에 새로 2를 만들어서 그 주소를 7103에 주소를 새로 바꿔치기 해줘야 된다.
주소...1002100310041005...
데이터이름: obj
값: @5002

주소...5002500350045005...
데이터@7103 ~ ?1'bbb'2

주소...7103710471057106...
데이터이름: a
값: @5005
이름: b
값: @5004

그러면 여기까지 obj.a에 있는 값은 5005로 변경이 됐지만, obj 이름이 가리키고 있는 주소는 변경되지 않았다.


—> 객체는 obj.a 프로퍼티의 값을 변경해도 변하지 않는다. 이게 기본형과 참조형의 차이점이다.


중첩 객체

let obj = {
  x: 3,
  arr: [3, 4],
}
  1. 일단 obj를 1002번에 확보하고 그 확보된 공간에 객체를 담아야 되니까 5002번에 있는 주소를 연결하고,

  2. 그 5002번에 있는 주소는 여러개의 자리를 미리 만들고 7103 ~ 를 가리키고 있다.
주소...1002100310041005...
데이터이름: obj
값: @5002

주소...5002500350045005...
데이터@7103 ~ ?

주소...7103710471057106...
데이터

3. x property를 할당해야되니까 7103에다가 이름에는 x를 넣고, 값에다가는 5003번에 있는 3의 값의 주소를 넣는다.
주소...1002100310041005...
데이터이름: obj
값: @5002

주소...5002500350045005...
데이터@7103 ~ ?3

주소...7103710471057106...
데이터이름: x
값: @5003

4. 다음 arr 이라는 이름을 가진 식별자를 7104에 부여했는데 여기에 있는 값을 넣으려고 보니까 또 다시 참조형 데이터이다.

그래서 또 많은 공간을 확보해둬야 돼서 5004번에 다가 8104 ~ 부터 공간을 확보해두었다.
그리고 5004번을 7104에다가 넣는다.

주소...1002100310041005...
데이터이름: obj
값: @5002

주소...5002500350045005...
데이터@7103 ~ ?3@8104 ~ ?

주소...7103710471057106...
데이터이름: x
값: @5003
이름: arr
값: @5004

주소...8104810581068107...
데이터

  1. 이제 arr 배열에 있는 값 3, 4를 넣기 위해서 메모리를 보면 이미 선언된 3이라는 값이 있어서 그걸 그대로 가져다 사용하면 된다.
    4는 없으니까 새로 만들어서 넣는다.
주소...1002100310041005...
데이터이름: obj
값: @5002

주소...5002500350045005...
데이터@7103 ~ ?3@8104 ~ ?4

주소...7103710471057106...
데이터이름: x
값: @5003
이름: arr
값: @5004

주소...8104810581068107...
데이터이름: 0
값: @5003
이름: 1
값: @5005



위의 상태에서 다시 obj.arr에 문자열 'hello'를 넣을 때를 살펴 볼 것이다.

obj.arr = 'hello';
주소...1002100310041005...
데이터이름: obj
값: @5002

주소...50025003500450055006...
데이터@7103 ~ ?3@8104 ~ ?4'hello'

주소...7103710471057106...
데이터이름: x
값: @5003
이름: arr
값: @5006

주소...8104810581068107...
데이터이름: 0
값: @5003
이름: 1
값: @5005
  1. 먼저 obj가 있는 1002를 찾아가서 5002를 찾아가고, 7103부터 찾으면서 arr을 찾는다.
  2. arr이 7104에 있고, 다시 @5004대신에 새로운 문자열을 만들어서 넣으랬으니까 5006번에 문자열을 만들고 5006을 새로운 값으로 할당한다.
  3. 그러면 이 부분의 값을 들고있는 데이터가 없어지게 된다.
  4. 5004번이 없어짐으로써 참조하고있는 값이 사라지게되니까 5004번이 갖고있던 값들도 다 사라진다.
    —> Garbage Collecting을 당하게 된다. —> 참조 카운트(참조를 하는 대상이 몇 개가 있는지?) 가 0이 됐다.
주소...50025003500450055006...
데이터@7103 ~ ?3@8104 ~ ?4'hello'

주소...810481058106 8107...
데이터이름: 0
값: @5003
이름: 1
값: @5005

변수 복사 살펴보기

기본형 데이터는 복사를 해도 가리키고 있는 주소를 그대로 가져오니까 같은 주소를 보게된다.

let a = 10;
let b = a;

let obj1 = { c: 10, d: 'ddd' };
let obj2 = obj1;

b = 15;
obj2.c = 20;


참조형 데이터의 내부에 있는 값을 바꿔도 둘이 같은 객체를 여전히 바라보고 있다.
그렇기 때문에 객체를 복사를 했음에도 불구하고 복사를 한 데이터의 값을 바꿨는데 원본데이터가 같이 바뀌는 이유를 알 수 있어야 된다.

var obj1 = {
  c: 10,
  d: 'ddd',
};
var obj2 = obj1;

해결 방안으로 매번 새로운 객체를 만들고, 불변성, 불변 객체를 만들어야 된다.


주소...1002100310041005...
데이터이름: a
값: @5002
이름: b
값: @5005
이름: obj1
값: @5003
이름: obj2
값: @5003

주소...50025003500450055006...
데이터10@7103 ~ ?'ddd'1520

주소...7103710471057106...
데이터이름: c
값: @5006
이름: d
값: @5004

기억해둘 것

기본형 데이터들은 한 번 만들어진 값이 똑같은 게 있으면 재사용을 한다.
숫자의 값이 엄청나게 커졌을 경우, 똑같은 메모리에서 1개만 쓰는 것.
—> 똑같은 값을 사용하면 1개의 메모리만 사용한다.


JavaScript의 메모리 관리

C언어같은 저수준 언어에서는 메모리 관리를 위해 malloc, free를 사용한다고 한다.
반면에 자바스크립트는 객체가 생성되었을 때 자동으로 메모리를 할당하고 쓸모 없어졌을 때 자동으로 해제한다. 이것을 가비지 컬렉션이라고 한다.

이러한 자동 메모리 관리는 잠재적 혼란의 원인이기도 한데, 개발자가 메모리 관리에 대해 고민할 필요가 없다는 잘못된 인상을 줄 수 있다고 한다.


메모리 생존주기

  1. 필요할 때 할당한다.
  2. 사용한다. (읽기, 쓰기)
  3. 필요없어지면 해제한다.
post-custom-banner

0개의 댓글