[코어 자바스크립트] 01_데이터 타입

Mooongs·2022년 5월 9일
0

코어자바스크립트

목록 보기
1/8
post-thumbnail
post-custom-banner

1. 데이터 타입의 종류

차이점

기본형(Primitive Type)값이 담긴 주솟값을 바로 복제하는 반면
참조형(Reference Type)은 값이 담긴 주솟값으로 이루어진 묶음을 가리키는 주솟값을 복제한다.

이 참조형 설명을 들었을 때는 무슨 소리인가...했는데 뒤에서 예시를 보며 점차 이해할 수 있게 되었다. 일단 고우!

2. 데이터 타입에 관한 배경지식

2-1. 메모리와 데이터

비트: 0 또는 1로 표현할 수 있는 하나의 메모리 조각
각 비트는 고유한 식별자를 통해 위치를 확인할 수 있다.

C/C++, 자바와 같은 정적 타입 언어는 메모리 낭비를 최소화하기 위해 데이터 타입별로 할당할 메모리 영역을 2바이트, 4바이트 이런 식으로 정해놓고 사용한다. 반면 자바스크립트는 정적 타입 언어에 비해 메모리 관리에 있어 더욱 자유로워졌다. 예를 들어, 자바스크립트숫자의 경우 정수형과 부동소수형을 구분하지 않고 8바이트(64비트)를 확보한다.

이렇듯 모든 데이터는 바이트 단위의 식별자, 즉 메모리 주솟값을 통해 서로 구분하고 연결할 수 있게 된다.

2-2. 식별자와 변수

변수 : 변경 가능한 데이터가 담길 수 있는 공간
식별자 : 어떤 데이터를 식별하는 데 사용하는 이름

3. 변수 선언과 데이터 할당

var a;

이를 말로 풀면 "변할 수 있는 데이터(변수)를 만든다. 이 데이터의 식별자는 a로 한다"와 같다. 아직은 변수를 선언만 한 단계로, 이에 대한 메모리 영역의 변화를 그림으로 나타내면 다음과 같다.

이후 누군가 a에 접근한다면 컴퓨터는 메모리에서 a라는 이름을 가진 주소를 검색한 뒤 이 공간 안에 담긴 데이터를 반환하게 되는 것이다.

var a = 'abc';

위처럼 변수에 데이터를 할당하게 되면 a라는 이름의 주소에 바로 할당을 하는 것이 아니라, 데이터를 저장하기 위한 별도의 메모리 공간을 확보해서 문자열 'abc'를 저장하고 그 주소를 변수 영역에 저장하는 식으로 이뤄진다. 실제로 변수 영역, 데이터 영역이라는 정식 명칭은 없지만 이해를 돕기 위해 이 책에선 이렇게 구분이 되어 있다.

❓ 왜 변수 영역에 값을 직접 대입하지 않을까?

1. 자유로운 데이터 변환
자바스크립트는 문자열에 대해 정해놓은 규격이 없고, 언어마다 필요한 메모리 용량이 가변적이다. (영어는 1바이트, 한글은 2바이트 필요)

만약 데이터의 공간이 이미 확보되어 있고, 이 데이터가 중간에 위치하는 상황이라면? 뒤에 오는 모든 데이터들을 다 옮겨야 하는 문제가 발생한다.

2. 효율적인 메모리 관리
중복된 데이터가 있을 경우, 하나의 데이터만 별도의 공간에 저장하고 필요한 경우에 그 주소만 변수에 입력되면 된다.

4. 기본형 데이터와 참조형 데이터

4-1. 불변값

불변성 여부를 구분할 때의 대상은 변수 영역이 아닌 데이터 영역의 메모리이다. 그리고 숫자, 문자열과 같은 기본형 데이터는 모두 불변값이다.

var a = 'abc';
a = a + 'def;

위와 같이 변수 a에 데이터를 할당했다가 새로운 문자열을 추가하면 기존의 'abc'가 바뀌는 것이 아니라 'abcdef'라는 새로운 문자열이 생기고 이 주소가 변수 a에 저장되는 방식이다.

즉, 이렇게 한 번 만들어진 데이터 값은 가비지 컬렉팅을 당하지 않는 한 절대 변하지 않는다. (= 불변!)

가비지 컬렉팅 : 자신의 주소가 더이상 참조되지 않으면 자동적으로 수거되는 것

4-2. 가변값

참조형 데이터는 설정을 통해 불변값으로 사용할 수도 있지만, 기본적으로는 가변값이라고 생각하면 된다.

var obj1 = {
	a: 1,
    b: 'bbb'
}

여기서부터 살짝 멘붕이 왔지만 몇차례 읽으니 조금씩 이해가 가기 시작했다. 참조형은 기본형과 다르게 객체의 변수 영역이 별도로 존재한다는 것이 가장 큰 차이점이다. 위 예시에서 obj1 안의 a, b와 같은 프로퍼티들을 저장하기 위한 별도 영역의 주소를 가지고 있는 것이다.

다시 예시의 데이터 할당 과정을 보면,

  1. obj1을 변수 영역에 저장하는 것까지는 같다.
  2. 객체 안의 프로퍼티들을 저장하기 위해 별도의 변수 영역을 마련하고 이 주소들을 데이터 영역에 저장한다. (@5001)
  3. 객체의 변수 영역인 @7103, @7104에 프로퍼티 이름을 저장한다. (여기서는 a와 b)
  4. 1과 'bbb'라는 프로퍼티 값을 데이터 영역에서 찾아봤는데 없기 때문에 @5003, @5004에 저장하고 이 주소를 프로퍼티 변수 영역에 저장한다.

객체 obj1@5003, @5004를 직접 갖는 것이 아니라 프로퍼티 그룹의 주솟값을 가지고 있는다는 것이 중요하다. 그렇기 때문에 내부 프로퍼티의 값이 변해도 obj1의 값이 변하는 것이 아니라 프로퍼티가 가진 주솟값이 변경된다.

4-3. 변수 복사 비교

기본형은 주솟값을 복사하는 과정이 한번만 이뤄지고, 참조형은 (프로퍼티 때문에) 한 단계를 더 거치게 된다는 차이가 있다.
이 둘의 차이는 변수가 복사될 때 더욱 두드러진다. 기본형 데이터가 복사된 뒤 값이 변경되면 새로운 주소를 참조하게 되지만 (원래의 데이터 값은 우두커니 불변!), 참조형의 경우 내부 프로퍼티 값이 바뀌면 객체의 변수 영역(아까 그 제3의 영역)이 바라보고 있는 주솟값이 바뀔뿐, 객체를 담고 있는 변수가 바라보고 있는 주소 자체가 변하지는 않는다. 즉, 참조형 데이터의 '가변성'은 데이터 자체가 아니라 내부 프로퍼티가 변경할 때만 성립된다.

5. 불변 객체

5-1. 불변 객체를 만드는 간단한 방법

❓ 불변 객체가 필요한 경우

값으로 전달받은 객체에 변경을 가해도 원본 객체는 변하지 않아야 할 때!
= 변경 전과 후에 서로 다른 객체를 바라봐야 할 때

💡 불변성을 유지하는 방법

  1. 새로운 객체를 재할당하기 (비효율적)
  2. 라이브러리 사용하기 (ex. immutable.js, baobab.js)
  3. ES6의 spread operator, Object.assign 메서드 사용하기
  4. 사용자 정의 함수 사용하기
  5. JSON 사용하기 (문자열로 전환했다가 다시 JSON 객체로 바꾸는 것)

5-2. 얕은 복사와 깊은 복사

5-2-1. 얕은 복사

객체가 담겨 있는 변수를 다른 변수에 할당하면 데이터 복사가 아닌 참조가 일어나게 된다.
데이터가 새로 생성되는 것이 아니기 때문에 결국 한 데이터를 공유하게 되는 것이다.

const user1 = {
	name: "Nayoung"
};

const user2 = user1;

user1.name = "Hayoung";

console.log(user1.name, user2.name) // Hayoung Hayoung
console.log(user1 === user2) // true - 같은 데이터 주소를 바라보고 있음

5-2-2. 깊은 복사

데이터 참조가 아니라 객체를 그대로 복사함으로써, 한 객체의 변경이 다른 객체의 데이터에 영향을 미치지 않는다.
(얕은 복사와 깊은 복사를 각각 할 수 있는 방법에 대해서는 추후에 포스팅할 예정이다.)

6. undefined와 null

이 내용은 이전에 정리해둔 적이 있어 링크만 첨부합니다.
👉 보러가기

profile
#FE개발자🐣 #새로운건 #짜릿해
post-custom-banner

0개의 댓글