Javascript

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

minjaem 2024. 2. 18. 22:08

데이터 타입의 종류

기본형(원시형, Primitive Type)

숫자, 문자열, 불리언, null, undefined

참조형(Reference Type)

객체, 배열, 함수, 날짜, 정규표현식과 ES6에서 추가된 Map, Set 등이 객체의 하위 분류에 속한다.

 

그렇다면 어떤 기준으로 기본형과 참조형을 구분하는 걸까?

기본형은 값이 담긴 주솟값을 바로 복제하는 반면, 참조형은 값이 담긴 주솟값들로 이루어진 묶음을 가리키는 주솟값을 복제한다.
기본적으로 이를 기본형은 불변값이고 참조형은 가변값이라고 표현한다.

 

 

변수 선언과 데이터 할당

// 1번
var a;
a = 'abc';

// 2번
var a = 'abc';

위 예시에서, 1번은 변수 a를 선언하고 다음 줄에 a에 'abc'라는 값을 할당했다. 2번은 같은 선언과 할당을 한 문장으로 표현했다. 자바스크립트 엔진은 동일하게 해석할까?

정답은 그렇다. 자바스크립트 엔진은 결국 같은 동작을 수행한다.

선언 과정메모리에서 비어있는 공간을 확보하고, 그 공간의 이름을 설정한다. 할당 과정 데이터를 저장하기 위한 별도의 메모리 공간을 다시 확보하고 문자열 'abc'를 저장한 뒤에 그 주소를 변수 영역에 저장한다.

 

그렇다면 왜 자바스크립트는 변수 영역에 값을 직접 대입하지 않고 굳이 번거롭게 한 단계를 더 거칠까?

데이터 변환을 자유롭게 할 수 있게 함과 동시에 메모리를 더욱 효율적으로 관리하기 위해서이다.

 

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

상수와 불변

상수는 변수에 데이터를 재할당할 수 없는 변수이며

불변은 메모리에 있는 데이터를 변경할 수 없음

불변값

한 번 할당하여 만든 값은 바꿀 수 없고, 다른 값으로 변경할 수도 없다. 변경은 새로 만드는 동작을 통해서만 이뤄진다.

한 번 만들어진 값은 가비지 컬렉팅을 당하지 않는 한 영원히 변하지 않는다.

가변값

참조형 데이터에서 한 번 만든 값을 변경한다. 단, 그 내부의 프로퍼티를 변경할 경우에만 '가변'은 성립한다.

데이터 자체를 변경할 경우에는 값이 달라진다.

 

기본형 데이터와 참조형 데이터의 저장 방식

대부분은 '기본형은 값을 복사하고 참조형은 주솟값을 복사한다'고 설명하고 있지만, 사실은 어떤 데이터 타입이든 변수에 할당하기 위해서는 주솟값을 복사해야하기 때문에, 엄밀히 말하자면 자바스크립트의 모든 데이터 타입은 참조형 데이터 타입일 수 밖에 없다.

다만, 기본형은 주솟값을 복사하는 과정이 한 번만 이뤄지고, 참조형은 한 단계를 더 거치는 것이다.

 

얕은 복사와 깊은 복사

얕은 복사

참조값만 복사하여 원본과 사본이 모두 동일한 주솟값을 가진다.

깊은 복사

모든 값들을 찾아내 하나하나 복사하는 방법으로 내부의 값을 복사하여 새로운 객체를 만든다. 그러므로 원본과 사본이 다른 주솟값을 가지게 된다.

Spread Operator와 Object.assign()을 통하여 1depth까지 깊은 복사를 할 수 있다. 중첩 객체까지 모두 완벽히 깊은 복사를 하기 위해서는 재귀 함수를 이용해서 하나하나 모두 복사할 수 있다.

 

리액트에서 얕은 복사와 깊은 복사 활용

리액트는 상태(state) 변경을 감지할때 Object.is()를 이용하여 얕은 비교를 한다.

깊은 복사로 내부에 중첩된 모든 객체의 변화를 감지하면 성능이 떨어지기 때문에 얕은 비교를 통해 참조값이 변경되면 감지를 한다.

여기서, 리액트에서 불변성을 유지해야 한다는 말이 중요하다.

리액트는 얕은 비교를 통해 상태 변경을 감지하기 때문에 사이드 이펙트 없는 정확한 상태(state)관리를 하기 위해서는, 

불변성을 유지하여 참조값을 완전히 변경시켜주어야 한다.

 

undefined와 null

undefined를 반환하는 세 가지 경우

1. 값을 대입하지 않은 변수 즉, 데이터 영역의 메모리 주소를 지정하지 않은 식별자에 접근할 때

2. 객체 내부의 존재하지 않는 프로퍼티에 접근하려고 할 때

3. return 문이 없거나 호출되지 않는 함수의 실행 결과

null

값이 없을때 나타내며 '비어있음'을 명시적으로 나타내고 싶을 때는 undefined 대신에 null을 쓰면 된다.

undefined와 null은 비슷한 의미이지만, 비어있다는 의미를 만들어 내기 위해서 만들어진 타입이기 때문에 개발할 때 undefined와 null은 적시에 명시적으로 사용해야 한다. 단, null은 한 가지 주의할 점이 있는데 바로 typeof null이 object라는 점이다. 이는 자바스크립트 자체 버그이므로 어떤 변수의 값이 null인지 여부를 판별하기 위해서는 typeof 대신 다른 방식으로 접근해야 한다.

 

 

* 정리하며 다시 스스로 생각해볼 질문

1. 책에서 설명하고 있는 변수 선언과 할당의 원리에 대해서 설명해주세요.

=> 그렇다면 자바스크립트에서 변수 영역에 값을 직접 대입하지 않고 굳이 번거롭게 더 한 단계를 거칠까?

2. 상수와 불변의 차이는 무엇인가요?

3. 자바스크립트의 데이터 타입을 설명해주세요.

4. null과 undefined의 차이는 무엇인가요?

5. 개발자가 변수에 undefined를 할당하지 않았는데, 출력되는 경우는?

6. 얕은 복사와 깊은 복사의 차이는 무엇인가요? 불변성이 왜 필요한가요?

7. 리액트의 얕은 복사와 깊은 복사는 어떻게 활용되고 있나요?