JavaScript
에는 8개의 데이터 타입이 있다. 원시 타입(primitive type)
7개와 객체 타입(object/reference type)
1으로 분류된다.
원시 타입
에는 number
, BigInt
, string
, boolean
, undefined
, null
, symbol
이 있고, 객체 타입
은 함수, 배열, 객체 등이 있다.
다른 언어와 다르게 JS
는 모든 수를 실수로 처리하는 하나의 숫자 타입만 존재한다. 정수와 부동 소숫점 숫자만 나타낸다. 따라서, 정수끼리 나누더라도 실수를 표현할 수 있다.
const int = 1; // 양수
const float = 1.2; // 실수
const minusInt = -1; // 음수
const binary = 0b01000001; // 2진수 65
const octal = 0o101; // 8진수 65
const hex = 0x41; // 16진수 65
number type
은 +, -, *, /, %, **, ++, --
등의 산술 연산자로 계산할 수 있다.
추가로 세 가지 특수 숫자값을 포함한다. 양의 무한대 Infinity
, 음의 무한대 -Infinity
, 산술 연산 불가 NaN(Not a Number)
이다. 평가 가능한 값이므로 변수에 할당할 수 있다.
console.log(10 / 0); // Infinity
console.log(10 / -0); // -Infinity
console.log(1 * 'a'); // NaN
const infinity = Infinity;
const minusInfinity = -Infinity;
const notANumber = NaN;
console.log(infinity, minusInfinity, notANumber); // Infinity -Infinity NaN
특수 숫자값의 장점은 불가능한 연산을 에러처리 하지 않더라도 프로그램을 죽이지 않는다는 점이다. 물론, 그 자유로움 때문에 잘못된 프로그램이 동작할 수 있다는 단점이 있다.
number
는 (253-1)
보다 큰 값 혹은 -(253-1)
보다 작은 값을 나타낼 수 없다. BigInt
는 number
가 나타낼 수 없는 숫자를 표현할 수 있다. 값 끝에 n
을 붙여 할당한다.
const bigInt = 1234567890123456789012345678901234567890n;
const nums = 1234567890123456789012345678901234567890;
console.log(typeof bigInt, typeof nums); // bigint number
console.log(bigInt === nums); // false
BigInt
와 number
는 연산할 수 없다. 만약 그러한 연산이 필요한 경우, BigInt()
나 Number()
함수를 사용하여 변환 후 연산한다.
// number 와 BigInt는 연산할 수 없다.
const aa = nums + bigInt
// TypeError: Cannot mix BigInt and other types, use explicit conversions
// number를 BigInt()로 변환하거나
const numToBig = BigInt(nums);
console.log(typeof numToBig); // bigint
console.log(bigInt + numToBig); // 2469135780246913636008807796973844237010n
// bigint를 Number()로 변환하여 연산한다.
const bigToNum = Number(bigInt);
console.log(typeof bigToNum); // number
console.log(nums + bigToNum); // 2.4691357802469137e+39
하지만 비교적 최근(ES11
)에 등장한 자료형이어서 지원하지 않는 브라우저가 있을 수 있다. can I use에서 브라우저 별 지원 여부를 확인한 후 사용할 것을 권장한다.
따옴표('')
, 큰따옴표("")
, 백틱(``)
으로 묶은 값은 문자열(string
) 타입으로 평가된다. 상기 기호로 감싸지 않으면 자바스크립트 엔진은 키워드나 식별자로 해당 문자를 인식한다.
const noQuote = hello;
const quote = 'hello';
console.log(noQuote); // ReferenceError: hello is not defined
console.log(quote); // hello
string
은 변경 불가능한 값(immutable value)이다. 하나의 문자를 변경해도 적용되지 않는다.
const str = 'hello';
str[0] = 'H';
console.log(str[0]); // h
따옴표와 큰따옴표는 줄바꿈이 되지 않아 이스케이프 시퀀스 중 하나인 \n
을 사용한다. 백틱을 사용하면 개행 문자 없이도 줄바꿈을 할 수 있다.
const quoteStr = "hello\nmy nickname is\nreal-bird";
const backtickStr = `hello
my nickname is
real-bird
`;
console.log(quoteStr);
console.log(backtickStr);
/* 둘 다
hello
my nickname is
real-bird */
문자열 연산자 +
를 통해 변수를 문자열 내에 삽입할 수 있지만, 백틱을 사용하면 좀 더 편하다. ${}
안에 변수를 삽입한다.
const nickname = "Real-Bird";
console.log("my nickname is " + nickname);
console.log(`my nickname is ${nickname}`);
/* 둘 다
my nickname is Real-Bird */
true(참)
와 false(거짓)
를 나타내는 데이터 타입이다. 조건 분기가 필요할 때 주로 사용한다.
true
는 암묵적으로 1
의 값을, false
는 0
의 값을 가진다. 따라서 숫자 연산자를 사용할 수도 있다. 반대로, 연산의 결과를 boolean
값으로 활용하는 것도 가능하다.
let x = true;
let y = false;
console.log(x * y); // 0
const z = 543 - 542 ? true : false;
console.log(z); // true
연산 결과를 boolean
값으로 활용할 경우, 0
이 아닌 모든 결괏값은 true
로 취급한다.
const zero = 3 - 3 ? true : false;
const one = 3 - 2 ? true : false;
const two = 3 - 1 ? true : false;
const minusOne = 3 - 4 ? true : false;
console.log(zero, one, two, minusOne); // false true true true
JS
는 변수를 초기화할 때 암묵적으로 값이 할당되지 않은 상태인 undefined
를 할당한다. 이는 자바스크립트 엔진이 사용하는 값으로, 개발자가 의도적으로 할당하지 않는 것이 좋다.
let temp;
console.log(temp); // undefined
undefined
처럼 값이 없는 상태를 나타내지만, 개발자가 의도적으로 할당할 때 사용한다. 변수에 null
을 할당하는 것은 변수가 더는 이전 값을 참조하지 않겠다는 의미가 된다. 참조를 명시적으로 제거했으므로 자바스크립트 엔진은 GC(Garbage Collection)
를 수행해 메모리를 비운다.
let temp = 'abc';
temp = null;
console.log(temp); // null
ES6
에서 추가된 원시 타입 자료형
이며 변경 불가능한 값(immutable value)이다. symbol
값은 다른 값과 중복되지 않는 유일무이한 값으로, 이름 충돌 위험이 없는 객체의 유일한 키를 만들기 위해 사용한다.
Symbol()
를 사용해 값을 생성한다.
const key = Symbol();
console.log(key); // Symbol()
괄호 안에 Symbol
의 설명을 추가할 수 있다. 단, 유일무이한 값이므로 같은 설명을 입력했더라도 다른 값으로 취급한다. 또한, description
과 toString
으로 형 변환할 수 있다.
const key1 = Symbol('temp');
const key2 = Symbol('temp');
console.log(key1 === key2); //false
console.log(key1.description); // temp
console.log(key1.toString()); // Symbol(temp)
속성 키 사용은 다음과 같다.
const obj = {};
obj[key1] = 1;
obj[key2] = 1;
console.log(obj);
/*{
Symbol(temp): 1
Symbol(temp): 1
}*/
키의 형태는 같지만, Symbol
특성 덕분에 각각 다른 속성으로 다뤄진다.
전역 Symbol
은 for()
와 keyFor()
로 관리한다. for()
는 저장된 키값이 없다면 새로운 symbol을 만든다. keyFor()
는 저장된 전역 symbol 키를 추출한다.
const temp1 = Symbol.for('temp');
console.log(Symbol.keyFor(temp1)) // temp
// 전역이 아닌 Symbol은 keyFor로 추출 불가능
const temp2 = Symbol('temp');
console.log(Symbol.keyFor(temp2)) // undefined
JS
는 객체 기반 언어이며 원시 타입
을 제외한 거의 모든 것이 객체이다. 원시 타입
은 물론 여타 객체 타입
까지 하나의 단위로 구성할 수 있는 복합적인 자료구조이며, 변경 가능한 값(mutable value)이다. 객체는 중괄호({}
)나 new Object()
로 만들 수 있다. object
는 key
와 value
로 구성된 property
를 가진다. property
가 함수인 경우는 method
라고 부른다.
const obj1 = {};
const obj2 = new Object();
const obj3 = {
property: "value",
method: () => console.log("hello"),
}
console.log(obj3.property); // value
obj3.method(); // hello
객체
내부에 찾는 프로퍼티가 없으면 undefined
를 반환한다. 표현식을 통해 동적으로 값을 할당하거나 변경할 수 있다. delete
로 프로퍼티를 삭제한다.
console.log(obj3.id); // undefined
obj3.id = 1;
console.log(obj3.id); // 1
delete obj3.id;
console.log(obj3.id); // undefined
참고
모던 자바스크립트 Deep Dive - 이응모, 위키북스
JAVASCRIPT.INFO - 자료형
JAVASCRIPT.INFO - 심볼형
JAVASCRIPT.INFO - 객체