[#JS] 변수와 자료형

RookieAND·2022년 7월 8일
0

Javascript

목록 보기
1/19
post-thumbnail

📖 Before Start

이 글은 Javascript 내용을 복습하는 차원에서 작성되었습니다.

Javascript 라는 언어에 입문한지도 어느덧 한 달이라는 시간이 흘렀다.

그간 여러가지 기능들을 구현하면서 나름대로 JS를 잘 쓰고 있다 생각했지만
문법과 관련된 내용을 종종 잊는 경우가 많아, 확실한 기초를 다지고자 한다.

✒️ let, const

let, const 는 JS에서 지원하는 변수 선언 관련 키워드이다.

let 키워드는 변수의 재할당, 재선언을 가능하도록 하는 키워드다.
Swift 에서는 이 녀석을 var 로 처리했는데, JS에서는 let 이란다.

const 키워드는 주로 상수 (Constant) 를 선언하기 위해서 같이 쓰인다.
상수로 초기화된 변수는 값을 변경할수도, 이를 다시 선언할 수도 없다.

let number = 100;
const constant = 200;

number = 200; // (0)
constant = 300; // (X)

왜 굳이 변수와 상수를 구분짓느냐면, 의도치 않은 실수를 방지하기 위함이다.

만약 내가 절대로 값이 변하면 안되는 변수를 하나 선언했다고 가정하자.
하지만 다른 팀원 중 한 명이 해당 변수의 값을 변경했다면? 문제가 터진다.
따라서 const 키워드는 이러한 문제를 사전에 방지하기 위해 사용된다.

✒️ Primitive Type / Reference Type

먼저, 원시 타입참조 타입의 차이점에 대해서 먼저 알아보자.

원시 타입이란, 정수와 문자 등의 실제 데이터 값을 저장하는 타입이다.
반대로 참조 타입이란, 특정 객체의 메모리 주소를 참조하는 타입이다.

원시 타입을 변수에 할당할 경우, 값 (Value) 을 그대로 저장하지만,
참조 타입의 경우 객체의 메모리 주소를 저장하여 참조하는 방식이다.

let arr_first = [1, 2, 3];
let arr_second = arr_first;

arr_second.push(4);
console.log(arr_first);  // [1, 2, 3, 4]
console.log(arr_second); // [1, 2, 3, 4]

상단의 코드를 보면, 분명 다른 배열에 push() 메소드를 사용했지만
결과적으로는 두 배열 모두 새로운 요소가 추가되었다. 대체 왜일까?

그 이유는 두 변수 arr_first, arr_second 가 같은 주소를 참조하기 때문이다.
따라서 한 쪽에서 값을 수정했다면, 그 결과는 다른 변수에도 영향을 미치게 된다.

let number_first = 10;
let number_second = number_first;

number_second = 20;
console.log(number_first);  // 10
console.log(number_second); // 20

그와는 반대로, 원시 타입인 Number 자료형을 담은 두 변수의 경우,
한 쪽의 값을 수정해도 다른 변수의 값에는 영향을 전혀 끼치지 않는다.

number_second 변수를 생성할 때, 단순히 number_first 변수의 값을 가져와
할당시켰기 때문에, 참조 타입처럼 두 변수가 같은 주소를 공유하는 것이 아니다.


여기서 중요한 점은, 원시 타입은 불변성 (Immutable) 을 가진다는 것이다.
따라서 값이 새롭게 변경되었을 경우, 이를 또 다른 메모리 공간에 저장한다.

let b = 100;
b += 100;

상단의 코드를 보자, 변수 b 에 100 이라는 Number 타입의 값이 할당되었다.
따라서 메모리에 새로운 공간을 할당시키고, 거기에 100 이라는 값을 저장한다.

이후 값이 변경됐다면 기존에 100 이 담긴 주소의 값을 변경하는 것이 아니라
또 다른 메모리 공간을 할당하고, 거기에 새롭게 변경된 값인 200 을 추가한다.

❓ 그러면 100 이라는 값이 저장된 메모리 공간은 어떻게 되느냐?

JS 에서는 해당 메모리 주소을 가리키는 식별자가 하나도 없는 경우,
가비지 컬렉팅 (GC) 에 의해 자동으로 정리된다. 마치 Java 처럼 말이다.

✒️ Data Type

JS 에는 총 7개의 원시 타입 (primitive type) 이 존재한다.

✅ Number

JS 에서 Number 자료형은 -(2^53 - 1) ~ (2^53 - 1) 범위의 수를 표현할 수 있다.
다른 언어와는 달리, 정수형과 실수형을 구분짓지 않았다는 점이 정말로 특이했다.

또한, Number 자료형에서 별도로 제공하는 세 가지 키워드가 있다.
바로 -infinity, infinity, 마지막으로 가장 난해했던 NaN 이다.

const notANumber = Number("Num") // NaN
const isANumber = Number("100")  // 100

NaN (Not-a-number) 키워드의 경우 숫자가 아님을 나타내기 위해 쓰인다는데..
다른 언어의 경우 (Python, Java) 보통은 TypeError 를 통해 캐스팅을 방지한다.
하지만 JS 에서는 NaN 이라는 정말, 듣도보도 못한 키워드를 쓰길래 많이 당황했다.

그리고 Number.MAX_SAFE_INTEGERNumber.MIN_SAFE_INTEGER 를 사용하여
Number 자료형의 유효 범위에서 표현할 수 있는 최대 / 최소 값을 구할 수도 있다.


✅ BigInt

BigInt 자료형은 Number 자료형이 표현할 수 있는 범위 밖을 쓸 수 있게 해준다.
정수 끝에 n 을 붙이거나, 별도의 생성자 BigInt() 를 호출하여 사용할 수 있다.

const alsoHuge = BigInt(9007199254740991); // 9007199254740991n

한 가지 중요한 사실은, BigInt 타입과 Number 타입 간의 연산이 안된다는 것이다.
만약 두 타입의 변수에 대한 연산을 시도하려 한다면, TypeError 가 발생한다.


✅ Undefined, Null

undefined 키워드는 값을 할당하지 않은 변수에 자동으로 할당되는 값이다.
null 키워드의 경우, 해당 변수의 값이 없음을 의도적으로 명시하기 위한 값이다.

const isNull = null; // null
const isUndefined;   // undefined

여기서도 한 차례 멘붕이 왔었다. 대체 undefined 같은 키워드는 왜 만든거야?
다른 언어의 경우 변수를 초기화하지 않으면 null 값을 집어넣는 게 보통인데..

하지만 JS의 생태계가 그렇다니 그냥 그러려니 하고 넘어가는게 최선이라 생각한다.
undefined 는 아직 값이 할당되지 않은 변수를 의미한다는 것만 알아두면 된다.


그 외에도 StringSymbol, 마지막으로 Boolean 타입이 있지만
이는 추후에 다른 챕터에서 더 디테일하게 다루고자 한다.

📖 Conclusion

JS 는 너무 자유로운 언어라는 생각이 든다. TS의 필요성이 느껴진다.

왜 Javascript 를 두고 Typescript 가 개발되었을까를 생각했는데, 이유가 다 있는 것 같다.
가끔은 엄격한 제한을 두는 정적 타입의 언어가 그리워진달까, Java 가 딱 그랬는데 말이다.

📖 참고 자료 목록

  1. https://study-ihl.tistory.com/24
  2. https://developer.mozilla.org/ko/docs/Web/JavaScript/Data_structures
profile
항상 왜 이걸 써야하는지가 궁금한 사람

0개의 댓글