Primitive type(원시타입)과 Reference type(참조타입)은 프로그래밍의 근간이다. 이에 대한 이해도가 없다면 for문을 배워도 if를 배워도 금방 한계에 봉착한다. 어려운 것은 아니나, 그렇다고 빠르게 이해할 수 없었떤 두 가지를 정리한다. 간단 비교하고 시작하자면 원시타입은 정수, 실수, 불린 등 실제 데이터를 담은 것이고, 참조타입은 해당 데이터가 담긴 주소를 갖고 있다.
Primitive type
원시타입은 객체나 메서드가 아닌 데이터 그 자체를 갖고 있는 것을 말한다. 대부분의 저급 언어가 가진 특징이며, 이미 생성한 원시타입의 값은 불변하다는 특징을 갖는다. 자바스크립트에서 원시타입은 7개만 알면 끝이다(ES6 기준). 원시타입의 종류와 기본 특징은 아래와 같다.
string | 문자열 |
number | 실수, 정수 등을 모두 포함한 숫자(-(2^53 − 1)부터 2^53 − 1까지의 수). +Infinity, -Infinity, NaN 값도 포함. |
bigint | Number보다 더 큰 2^53-1 보다 큰 정수를 포함 |
boolean | true(참)과 false(거짓)으로 이뤄진 논리 데이터 |
undefined | 값을 할당하지 않은 상태 |
symbol | 유일하고 변경 불가능한 타입 |
null | 존재하지 않거나 유효하지 않은 상태(빈 상태) |
string이나 number등 한 번에 이해할 수 있는 타입이 있는 반면, undefined와 null, 그리고 symbol 같이 무슨 말인가 싶은 타입이 있다. 한 번에 서술하기엔 조금 길어질 수 있어 따로 정리했다. undefined와 null은 지난 번 이미 게재했고, 근시일 내에 symbol도 따로 정리할 예정이다. (이 글에는 전체적인 특징만 서술한다.)
불변?!
원시타입의 특징 중 하나인 불변한다는 점이 처음에 쉽게 와닿지 않는다. let을 쓰면 언제든 재할당이 가능하다는 의문이 바로 들기 때문이다. 이때 재할당 여부의 문제가 아니라 컴퓨터에서 동작하는 방식이다.
let bar = "abc";
console.log(bar); // abc
bar.toUpperCase();
console.log(bar); // abc
bar라는 변수에 abc 문자열을 넣은 후 출력했을 때와 bar라는 변수를 대문자료 변환시키는 toUpperCase()를 실행하고 다시 출력했을 때 모습이다. 결과값이 전혀 바뀌지 않은 것을 볼 수 있다. 원시타입의 경우 해당 값을 가지고 아무리 많은 변경을 주어도 해당 값은 변하지 않는다. 이게 불변하다는 점이다.
bar = bar.toUpperCase(); // ABC
위와 같이 코드를 쓰면 되는거 아니냐고 반문할 수 있다. 이는 원시 값에 새로운 값을 부여한 것으로 기존 값을 직접 변형한게 아니다. 이는 메모리에 저장된 상태를 보면 이해할 수 있다. 예를 들어 변수 bar은 Ox123이라는 주소를 할당받고 "abc"라는 값을 넣어둔 상태다. Ox123이라는 주소에 할당된 "abc"는 절대 변하지 않는다. 여기서 같은 변수에 재할당한다면? bar은 Ox124라는 주소를 다시 부여 받은 후 "ABC"라는 값을 넣는다. 이때 Ox123은 메모리에 그대로 남아있기에 원시타입은 불변하다고 말한다.
Reference type
참조 타입은 한문장으로 '원시 타입을 뺀 모든 것'이다. object(객체), array(배열)이 대표다.
object | { 키 : 값, 키 : 값 } 키와 값이 한쌍으로 이루어진 조합 뭉탱이 |
array | [ 값, 값, 값, 값 ] 값으로만 이루어진 뭉탱이 |
set | 유일한 값만 존재하는 값 콜렉션 객체 |
map | 키-값 쌍을 보유하고 키의 원래 삽입 순서를 기억하는 객체 |
원시 타입이 불변하다면 반대로 참조 타입은 언제든 바뀔 수 있느게 특징이다. 물론 이는 원시 타입과 같이 동작 방식에서 차이다.
const abc = [1,2,3,4,5]
console.log(abc) // [1,2,3,4,5]
위와 같이 선언했을 경우 abc가 Ox1111라는 주소를 할당 받고 여기에는 Ox2000이라는 값이 들어 있다. 이 값은 배열의 값이 아닌 배열이 담긴 값인 셈이다. Ox2000에 [1,2,3,4,5]가 들어 있다. 다시 정리해보다 abc 변수 주소는 Ox1111, 이 주소 담긴 값은 Ox2000이다. 참조 타입은 원시 타입과 다르게 값을 바로 가지지 않고 주소를 가지고 있다는게 다른 점이다. 이 특징으로 인해 const로 선언 했음에도 배열 내 값을 얼마든지, 바꿀 수 있고 문제도 없다. 다만, const가 상수인 만큼 배열로 설정했을 경우 배열을 객체로 바꾼다는 등의 다른 타입으로 바꾸는 건 불가능하다.
마무리
원시 타입과 참조 타입에 대한 이해를 처음엔 알고리즘 문제를 풀면서 필요하다 생각했고, 이후 웹페이지 중 게시판이나 댓글 리스트를 map으로 반복하게 하면서 조건값을 설정할 때 필요성을 느꼈다. 원시 타입과 참조 타입의 이해가 없이도 코딩하는데 무리가 없을 수 있다. 다만, 너무 없다면 리팩토링, 즉 최적화하는 데에 불편함 혹은 당혹감을 느끼기 쉽상이다. 알고나서 취사선택하는 것과 모르고 누가 짠 코드를 따라 최적화하는 건 장기적으로 한계를 느낄 수 있으니 미리미리 알아두는 게 좋은 부분이라 여긴다.
※ 잘못된 내용이 있을 경우 댓글로 알려주세요. 배우고 익히고 수정하겠습니다:)
'FE > Javascript' 카테고리의 다른 글
Shallow Copy & Deep Copy (0) | 2022.09.24 |
---|---|
== & === (1) | 2022.09.23 |
null & undefined (0) | 2022.09.15 |
let, const, var (1) | 2022.09.14 |
Destructuring Assignment (0) | 2022.09.13 |