자료형과 형 변환
typeof 연산자
로 변수의 자료형 확인하기
typeof
는 변수나 값의 자료형(데이터 타입)을 "문자열"로 반환하는 연산자이다.
js
let num = 123;
console.log(typeof num); // "number"
자료형 (Data Type)
less
자료형 (Data Type)
├── 원시타입 (Primitive Types)
│ ├── Number
│ ├── String
│ ├── Boolean
│ ├── Undefined
│ ├── Null
│ ├── Symbol
│ └── BigInt
└── 비 원시타입 / 참조 타입 (Reference Types)
└── 객체 Object
├── Array
├── Function
├── Date
├── RegExp
├── Map
├── Set
└── 기타 사용자 정의 객체
js
// 원시 타입 자료형: 단 하나의 값만 가지는 타입
let num = 100;
num = "one";
// 비 원시 타입은: 한번에 여러 개의 값을 가지는 타입
let arr = [100, "one", 1];
- 변수의 자료형이란 변수에 할당된 데이터의 종류를 뜻하며, 변수의 타입이라고도 부른다.
- 자료형은 크게 "원시 타입", "비 원시 타입"으로 나뉜다.
1. 원시 타입 (Primitive Type)
less
원시타입 (Primitive Types)
├── Number
├── BigInt
├── String
├── Boolean
├── Null
├── Undefined
└── Symbol
- 변수에 값이 직접 저장되며, 다른 변수에 복사해도 서로 독립적인 값으로 존재한다.
- 즉, 값 하나만 저장하고 그 값 자체로 동작하는 타입을 원시 타입이라 부른다.
(1) Number 숫자형
js
let number1 = 10;
let number2 = 10.01;
console.log(typeof number1); // "number"
console.log(typeof number2); // "number"
- Number 타입은 모두
IEEE 754 64-bit 부동소수점
으로 다뤄지기 때문에, 정수와 소수의 구분 없이 모두실수
(floating‑point)로 처리된다. - 이로 인해 큰 정수 연산이나 소수점 연산에서 정밀도(precision) 손실이 발생할 수 있다.
정밀도 손실 예시
js
// 큰 정수 연산 오차 예시
console.log(Number.MAX_SAFE_INTEGER); // 9007199254740991
console.log(Number.MAX_SAFE_INTEGER + 1); // 9007199254740992
console.log(Number.MAX_SAFE_INTEGER + 2); // 9007199254740992 ← 의도한 +2가 적용되지 않음
// 소수점 연산 오차 예시
console.log(0.1 + 0.2); // 0.30000000000000004
// 이유: IEEE 754 이진 부동소수점 표현 한계
js
// BigInt로 해결 (BigInt끼리만 연산 가능)
const big = 9007199254740991n;
console.log(big + 1n); // 9007199254740992n
console.log(big + 2n); // 9007199254740993n
console.log(big + 2); // TypeError: Cannot mix BigInt and other types
특수한 숫자 값들
Infinity
js
let num1 = Infinity;
console.log(typeof num1); // "number"
let num2 = 100 / 0;
console.log(num2); // Infinity
console.log(typeof num2); // "number"
- 무한대를 의미하는 값
- 변수에 하나의 값으로 직접 할당할 수 있고, 숫자를 0으로 나누거나, 너무 큰 값을 연산할 때 반환된다.
NaN (Not a Number)
js
let num3 = NaN;
console.log(typeof num3); // "number"
let num4 = "자바스크립트" / 10;
console.log(num4); // NaN
console.log(typeof num4); // "number"
- "숫자가 아님"을 의미하는 값
- 변수에 하나의 값으로 직접 할당할 수 있고, 부정확한 연산을 하게 될 경우에 반환되는 값(문자열을 숫자로 나누는 연산을 하게 될 경우)
(2) BigInt
js
let big1 = 9007199254740991n;
let big2 = BigInt("9007199254740991");
console.log(typeof big1); // "bigint"
console.log(typeof big2); // "bigint"
- Number가 "안전하게 표현할 수 없는" 매우 크거나 작은 정수를 다룰 때 사용하는 자료형
- Number 타입이 "안전하게 표현할 수 있는" 정수 범위: ±(2^53 - 1)
즉, 2^53 -1 보다 크거나 -(2^53 - 1) 보다 작은 정수 - BigInt 값은 숫자 뒤에 n을 붙이거나, BigInt() 함수를 사용하여 생성할 수 있다.
BigInt의 사칙연산
js
let big1 = 10n;
let big2 = 5n;
let num = 5;
console.log(big1 + big2); // 15n
console.log(big1 + num); // TypeError: Cannot mix BigInt and other types
- BigInt끼리만 연산이 가능하며, 일반 숫자(Number)와 혼합하여 연산할 수 없다.
2^53 -1
의 의미
Number
데이터 타입은 64비트(8바이트) 부동소수점 형식을 사용한다.
이 중 53비트가 정수 부분을 저장하는 데 사용된다.(나머지는 부호와 소수점 위치 정보)
따라서, 이 53비트로 표현할 수 있는 최대 정수는 2^53 -1
이다.2^53 -1
= 9,007,199,254,740,991 → 최대 정수값.-(2^53 -1)
= -9,007,199,254,740,991 → 최소 정수값.
이 범위를 벗어나면 정밀도 문제가 발생하기 때문에, BigInt가 필요하다.
BigInt
는 왜 정밀도 문제를 해결하는지?
BigInt
는 임의 정밀도를 지원하는 자료형이다. 즉, 숫자가 커질수록 그에 따라 저장공간이 동적으로 늘어나므로, 크기에 제한이 없고 매우 큰 정수를 정확하게 표현할 수 있다. 정수에 대한 정확한 연산을 지원하므로, 크고 작은 숫자 간 연산 시 정밀도를 잃지 않는다.
Number
: 64비트 부동소수점 방식을 사용하며, 정수 범위에 한계가 있어 정밀도 문제 발생BigInt
: 임의 크기 정수를 지원하여, 정밀도 손실 없이 큰 숫자를 정확하게 표현한다. 크기에 제한이 없어서 매우 큰 정수도 정확하게 다룰 수 있다.
(3) String
js
let name1 = "bin"; // 큰 따옴표
console.log(typeof name1); // "string"
- 문자열을 변수에 할당할 때는 따옴표로 문자열을 감싸야 한다.
- 큰 따옴표
""
와 작은 따옴표''
는 같은 기능을 하기 때문에 문자열 할당 시 아무거나 사용 가능하다.
템플릿 리터럴 방식(Template Literals)
js
let name = "bin";
let greeting = `안녕하세요. 제 이름은 ${name}입니다.`;
console.log(greeting); // 제 이름은 bin입니다.
- 백틱
``
을 사용하면 문자열을 만들 수 있는데, 이걸 템플릿 리터럴이고 부른다. - 템플릿 리터럴 안에서는
${}
구문을 사용해 문자열 내에 변수에 저장된 값이나 표현식을 쉽게 삽입할 수 있다.
문자열 이스케이프 문자
css
// 큰 따옴표: \"
console.log('He said, \"Hello!\"');
// 작은 따옴표: \'
console.log("It\'s OK.");
// 줄바꿈: \n
console.log("줄\n바꿈");
// 탭(들여쓰기): \t
console.log("탭\t탭");
js
He said, "Hello!"
It's OK.
줄
바꿈
탭 탭
- 문자열 안에 특수 문자를 넣고 싶을 때는 이스케이프 문자(\)를 사용한다.
\"
,\'
,\n
,\t
(4) Boolean
js
let isClicked = false; // 버튼이 클릭되었는지 여부
let isOpen = true; // modal이 열렸는지 여부
if (isClicked) {
console.log("클릭O");
} else {
console.log("클릭X");
}
true
,false
두 가지 값만 가질 수 있는 논리형 자료형이다.- 주로 조건문에서 참과 거짓을 판단할 때 사용된다.
- "어떤 상태인지", "조건이 만족되었는지" 와 같은 논리적인 상태를 표현할 때 유용하다.
(5) Null
js
let name = null;
console.log(typeof name); // "object" (자바스크립트의 오래된 버그)
console.log(name === null); // true
js
let selectedUser = null; // 아직 선택된 사용자가 없음
// 나중에 유저가 선택되면 값 할당
selectedUser = "hyebin";
- "값이 없음"을 명시적(의도적)으로 할당하는 자료형이다.
- 변수에 아직 값이 정해지지 않았지만, 일부러 비워두겠다는 의도를 표현할 때 사용한다.
- 주로 초기화가 필요한 변수에 사용되며, 값이 존재하지 않음을 나타낼 때 유용하다.
(6) Undefined
js
let name; // 변수 선언만 하고 값은 할당하지 않음
console.log(name); // undefined
console.log(typeof name); // "undefined"
undefined
는 값이 할당되지 않은 변수에 자바스크립트가 자동으로 할당하는 특별한 값(암묵적)이다.null
과 마찬가지로 "값이 없음"을 나타내는 자료형이지만, null이 명시적(의도적)으로 값이 없음을 나타내는 것과 달리,undefined
는 변수에 값이 아직 할당되지 않은 상태를 의미한다.
(7) Symbol
js
const sym1 = Symbol("id");
const sym2 = Symbol("id");
console.log(sym1 === sym2); // false
console.log(typeof sym1); // "symbol"
symbol
은 유일하고 변경 불가능한 원시 값을 만들기 위한 자료형이다.- 주로 객체의
고유한 프로퍼티 키(key)
로 사용된다. 같은 이름이라도 서로 다른 Symbol 값은 절대 같지 않기 때문에, 충돌 없이 안전하게 사용할 수 있다. - Symbol() 함수를 호출해서 생성하며, 선택적으로 설명을 붙일 수 있다.
- 주로 라이브러리나 프레임워크에서 객체 속성 이름이 겹치지 않게 하기 위해 사용한다.
- 심볼 값은 문자열로 변환할 수 없으며, 직접 출력하면 설명이 나오지만 고유한 식별자로 작동한다.
2. 비 원시 타입 (Reference Types)
less
비 원시타입 / 참조 타입 (Reference Types)
└── 객체 Object
├── 배열 Array
├── 함수 Function
├── 날짜 Date
├── 정규표현식 RegExp
├── Map
└── Set
- 비원시 타입은 변수에 값 자체가 아닌
그 값이 저장된 메모리 주소(참조값)
를 저장하는 자료형이다. - 즉, 변수는 실제 데이터를 직접 담지 않고, 데이터가 저장된 위치를 참조합니다.
- 대표적인 비원시 타입은
객체(Object)
이며, 배열, 함수 등도 객체의 일종이다 - 원시 타입과 달리, 비 원시 타입은 변경 가능한 값(mutable)이며, 여러 개의 값을 하나의 변수에 저장할 수 있다.
- 같은 객체를 여러 변수가 참조할 수 있고, 값을 변경하면 참조된 모든 변수에 영향을 미칠 수 있다.
비 원시 타입의 특징 #참조형
#변경 가능
참조형 (Reference Type)
js
let obj1 = { name: "Alice" };
let obj2 = obj1; // obj1과 obj2는 같은 객체를 참조함
obj2.name = "Bob";
console.log(obj1.name); // "Bob"
// obj2에서 수정한 값이 obj1에도 영향을 미친다.
- 변수에 저장되는 것은 값이 아니라 객체가 저장된 메모리 주소이다.
- 같은 객체를 참조하는 변수끼리는 서로 영향을 주고받는다. 즉, 복사된 객체를 수정하면 원본 객체도 영향을 받는다.
변경 가능 (Mutable)
js
let numbers = [1, 2, 3];
numbers[0] = 100; // 배열의 첫 번째 값 수정
console.log(numbers); // [100, 2, 3]
- 객체나 배열 같은 비 원시 타입은 내용을 자유롭게 수정하거나 속성을 추가할 수 있다.
- 메모리 주소(참조)는 그대로 유지된 채 내부 데이터만 변경된다.
객체 (Object)
js
let person = {
name: "Bin", // 문자열
age: 30, // 숫자
isEmployed: true, // 불리언
};
- 객체는
key: value
형태의 데이터 구조이다. - 객체의 값에는 문자열, 숫자, 불리언뿐 아니라 배열, 함수, 또 다른 객체도 들어갈 수 있다.
- 배열(Array), 함수(Function), 날짜(Date), 정규표현식(RegExp), Map, Set 등 모두 객체의 일종이다.
(1) 배열 Array
js
let colors = ["red", "green", "blue"];
let mixedArray = [1, "apple", true, [2, 3], { key: "value" }];
- 배열은 여러 개의 값을 순서대로 저장할 수 있는 자료형이다.
- 각 값은 숫자 인덱스를 통해 접근할 수 있으며, 배열 안에 다양한 타입의 값을 저장할 수 있다.
숫자 인덱스란?
자바스크립트에서 배열은 순서가 있는 값들의 집합이다. 배열의 각 요소는 0부터 시작하는 숫자 인덱스로 자동 부여되어, 해당 순서를 통해 값을 참조하거나 수정할 수 있다.
js
// 배열 선언
let fruits = ["apple", "banana", "cherry"];
// 배열에서 첫 번째 요소(apple)에 접근
console.log(fruits[0]); // "apple"
// 배열에서 두 번째 요소(banana)에 접근
console.log(fruits[1]); // "banana"
// 배열에서 세 번째 요소(cherry)에 접근
console.log(fruits[2]); // "cherry"
- 배열에 값 추가하기
배열은 인덱스를 통해 새로운 값을 추가할 수 있으며, 추가된 값에는 자동으로 다음 인덱스 번호가 할당된다.
js
let numbers = [10, 20, 30];
numbers[3] = 40; // 인덱스 3에 40을 추가
console.log(numbers); // [10, 20, 30, 40]
(2) 함수 Function
js
function greet(name) {
return `Hello, ${name}!`;
}
- 함수는 자바스크립트에서 객체의 한 종류로 취급된다.
- 일련의 명령문을 하나로 묶어, 필요할 때마다 호출할 수 있는 실행 블록이다.
- 주로 코드의 재사용을 위해 사용되며,
입력값(매개변수)
을 받아 처리하고,출력값(반환값)
을 반환할 수 있다.
3. Falsy & Truthy
- 자바스크립트에서는 모든 값이 불리언 문맥에서
truthy
orfalsy
로 변환된다. Boolean(value)
또는!!value
로 확인할 수 있다.
Falsy 값
값 | 설명 |
---|---|
false | 불리언 false 자체 |
0 | 숫자 0, 음수 0 |
0n | BigInt 0 |
"" , '' , `` | 빈 문자열 |
null | 명시적 빈(없음) |
undefined | 암묵적 빈(미할당) |
NaN | 숫자가 아님(Not a Number) |
js
Boolean(0); // false
Boolean(""); // false
Boolean(null); // false
Boolean(undefined); // false
Boolean(NaN); // false
Boolean(false); // false
Truthy 값
falsy
값이 아닌 나머지 모든 값은 truthy
로 평가된다.
값 | 설명 |
---|---|
"hello" | 빈 문자열이 아닌 모든 문자열 |
42 | 0이 아닌 모든 숫자 |
[] | 빈 배열도 truthy |
{} | 빈 객체도 truthy |
true | 불리언 true 자체 |
" " | 공백 하나 이상의 문자열 |
js
Boolean("hello"); // true
Boolean(42); // true
Boolean([]); // true
Boolean({}); // true
Boolean(" "); // true
Boolean(true); // true
형 변환 (Type Conversion)
자바스크립트는 동적 타입(Dynamic Typing) 언어이다.
js
let nowType = “안녕하세요”;
console.log(typeof nowType); // "string"
nowType = 100;
console.log(typeof nowType); // "number"
- 자바스크립트는 동적 타입(Dynamic Typing) 언어로, 변수에 저장된 값에 따라 자료형이 자동으로 결정된다.
- 따라서 같은 변수에 서로 다른 타입의 값을 할당해도 에러 없이 동작한다.
형 변환이란?
- 어떤 연산을 수행하기 위해 값의 자료형을 바꾸는 과정이다.
- 자바스크립트에서는 형 변환이 자동으로 발생하기도 하고, 개발자가 직접 지정할 수도 있다.
- 형변환에는
묵시적 형변환
,명시적 형변환
이 있다.
(1) 묵시적 형변환 (Implicit Type Conversion)
js
let result = "3" * 2;
console.log(result); // 6
console.log(typeof result); // "number"
- 묵시적 형 변환이란, 자바스크립트 엔진이 연산을 수행하기 위해
자동으로 자료형을 변환하는 것
을 말한다. - 위 예시처럼, 문자열 "3"을
*
연산을 위해 자동으로 숫자 3으로 변환하여 계산한다. - 사칙연산 중
/
,*
,-
연산은 "문자열"을 "숫자형"으로 변환한다. +
연산자는 문자열 결합 기능을 포함하고 있기 때문에, 연산 대상 중 하나라도 문자열이면 나머지 피연산자도 문자열로 변환하여 문자열로 결합하는 방식으로 처리한다.
(2) 명시적 형변환 (Explicit Type Conversion)
js
let num1 = "15";
let num2 = 5;
console.log(num1 + num2); // "155"
// + 연산자로 숫자도 문자열로 변환되어 문자열 결합
// 형변환
console.log(parseInt(num1) + num2); // 20
// parseInt 문자열을 정수로 변환해주는 함수 (정수로만 변환)
console.log(Number(num1) + num2); // 20
// Number 문자열을 숫자로 변환해주는 함수 (정수, 실수 모두 가능)
console.log(String(num2) + num1); // "515"
// String 숫자열을 문자열로 변환해주는 함수
- 명시적 형변환이란, 개발자가
의도적으로 자료형을 변환하는 것
이다. - 내장 함수 Number(), String(), Boolean() 등을 사용해 직접 타입을 바꾼다.