Skip to content
This page has been auto-translated and may contain errors.View in English

데이터 타입

docs.scrimba.com

누군가의 이름, 나이, 로그인 여부를 저장해 본다면 이미 세 가지 서로 다른 종류의 값을 사용한 셈입니다. 이름은 텍스트이고, 나이는 숫자이며, 로그인 여부는 예/아니오로 표현되는 값입니다. JavaScript는 이 각각을 별개의 타입으로 취급하고, 서로 다른 방식으로 처리합니다. 이 장에서는 가장 먼저 마주치게 될 몇 가지 타입과, 지금 다루고 있는 값이 어떤 타입인지 확인하는 방법을 다룹니다.

기본 타입

세 가지 타입이 여러분이 저장하는 값의 대부분을 차지합니다. **문자열(string)**은 인용부호로 감싼 텍스트입니다. **숫자(number)**는 세거나 계산할 때 쓰는 모든 수입니다. **불리언(boolean)**은 예/아니오 값이며, true 또는 false 두 가지 선택지만 가집니다.

js
const name = "지민"; // 문자열: 텍스트
const age = 27; // 숫자
const isLoggedIn = true; // 불리언: true 또는 false

이름, 메시지, 색상처럼 단어로 표현되는 것에는 문자열을 사용합니다. 세거나 계산할 수 있는 것에는 숫자를 사용합니다. 체크박스가 선택되었는지처럼 답이 둘 중 하나인 경우에는 불리언을 사용합니다. 이 타입들은 문자열숫자에서 더 자세히 다룹니다.

JavaScript에서 일상적으로 다루는 값들은 몇 가지 **타입**으로 나뉘고, 그중 세 가지가 데이터의 대부분을 차지합니다. **문자열(string)**은 인용부호로 감싼 텍스트로, 홑따옴표든 겹따옴표든 상관없습니다. **숫자(number)**는 모든 수치 값입니다. **불리언(boolean)**은 truefalse 딱 두 가지 값 중 하나입니다.

js
const productName = "무선 마우스"; // 문자열
const price = 24.99; // 숫자
const inStock = true; // 불리언

각 타입은 맡은 역할이 있습니다. 문자열은 표시하거나 읽는 텍스트를 담고, 문자열에서 다룹니다. 숫자는 계산에 사용하는 모든 것을 담고, 숫자에서 다룹니다. 불리언은 양자택일의 답을 담으며, price < 30 같은 비교식이 만들어내는 값이기 때문에 판단이 필요한 곳이라면 어디서든 등장합니다.

JavaScript는 값을 몇 가지 **타입**으로 분류하고, 그중 세 가지가 여러분이 다루는 데이터의 대부분을 차지합니다. **문자열(string)**은 인용부호로 감싼 문자들의 나열로, 홑따옴표, 겹따옴표, 또는 템플릿 리터럴을 위한 백틱을 사용할 수 있습니다. **숫자(number)**는 수치 값입니다. **불리언(boolean)**은 true 또는 false 두 값 중 하나입니다.

js
const currency = "EUR"; // 문자열
const balance = 1499.5; // 숫자
const isOverdrawn = balance < 0; // 불리언, 여기서는 비교 결과

문자열과 숫자의 구분은 처음 보기보다 훨씬 중요합니다. "5"5는 서로 다르게 동작하기 때문입니다. 하나는 숫자를 담고 있을 뿐인 텍스트이고, 다른 하나는 산술 연산이 가능한 값입니다. 불리언은 직접 손으로 입력하는 일이 거의 없기 때문에 일찍 눈여겨볼 만합니다. 불리언은 비교와 논리적 검사의 결과로 나오는 값이므로, balance < 0을 "불리언"으로 읽어낼 수 있어야 이후의 조건문과 연산자가 자연스럽게 이해됩니다.

Juno기본 타입 항상 손이 가는 세 가지 타입이 있습니다. 인용부호로 감싼 텍스트는 string, 수치는 number, true 또는 false 답은 boolean입니다. 저장하려는 것의 종류에 맞는 타입을 고르세요. 이름은 문자열, 나이는 숫자, 체크박스는 불리언입니다.
Juno기본 타입 세 가지 타입이 대부분의 역할을 합니다. 텍스트는 string, 수치 값은 number, true 또는 false 값은 boolean입니다. 인용부호가 있으면 문자열이므로, "5"는 숫자가 아니라 텍스트입니다. 불리언은 대개 직접 입력하는 값이 아니라 비교의 결과로 나타납니다.
Juno기본 타입 문자열, 숫자, 불리언이 데이터의 대부분을 차지하며, 문자열과 숫자의 경계선이 함정입니다. "5"는 텍스트이고 5는 산술 연산이 가능한 값입니다. 불리언 리터럴을 직접 쓰는 일은 거의 없는데, balance < 0 같은 비교식이 대신 만들어주기 때문입니다. 비교식을 "불리언이다"라고 읽어내는 것이 이후 조건문을 이해하는 열쇠입니다.

없음: null과 undefined

값이 없을 때도 있는데, JavaScript는 이를 표현하는 두 가지 방법을 가지고 있습니다. **undefined**는 아직 아무 값도 주어지지 않았다는 뜻입니다. 변수를 만들었지만 값을 설정하지 않으면, 그 값은 undefined가 됩니다.

js
let score;
console.log(score); // undefined

null은 의도적으로 비어 있다는 뜻입니다. "지금은 값이 없고, 그것은 의도된 것이다"라고 말하고 싶을 때 직접 사용합니다.

js
let winner = null;
console.log(winner); // null

짧게 말하면, undefined는 JavaScript가 "여기 아직 아무것도 없다"라고 말하는 것이고, null은 여러분이 "여기 아무것도 없다, 의도적으로"라고 말하는 것입니다.

두 값 모두 "값 없음"을 나타내지만, 누가 그 값을 설정했는지가 다릅니다. **undefined**는 JavaScript가 기본적으로 주는 값입니다. 예를 들어 값을 지정하지 않고 선언한 변수는 처음에 undefined로 시작합니다.

js
let selectedColor;
console.log(selectedColor); // undefined

null은 무언가를 의도적으로 비어 있다고 표시하기 위해 직접 대입하는 값으로, 비워둔 자리, 혹은 아직 채우지 않은 자리를 나타냅니다.

js
let couponCode = null;
console.log(couponCode); // null

undefined는 기본값으로서의 부재이고, null은 의도적인 부재입니다. 이렇게 구분해서 읽는 것이 유용합니다. undefined가 보이면 무언가가 아예 설정된 적이 없다는 뜻이고, null이 보이면 누군가가 의도적으로 비워두었다는 뜻입니다.

nullundefined는 둘 다 값의 부재를 나타내지만, 이 둘을 구분하는 관례는 의도와 관련되어 있습니다. **undefined**는 JavaScript가 스스로 만들어내는 부재입니다. 선언은 되었지만 값이 할당되지 않은 변수, 존재하지 않는 속성, 아무것도 반환하지 않는 함수가 그 예입니다.

js
let discount;
console.log(discount); // undefined

null은 "아직 손대지 않았다"가 아니라 "의도적으로 비어 있다"를 나타내기 위해 여러분이 직접 대입하는 부재입니다.

js
let appliedCoupon = null;
console.log(appliedCoupon); // null

이 둘을 구분해서 다루는 것은 코드베이스에서 실질적인 신호가 됩니다. undefined는 대개 누구도 값을 설정하지 않았다는 뜻이라 버그나 미완성된 흐름을 가리킬 수 있는 반면, null은 의도된 선택으로 읽힙니다. 또한 둘은 이후의 검사에서 동일하게 동작하지 않기 때문에, 비교와 연산자가 등장하면 이 둘을 섞어 쓸 때 혼란이 생깁니다. undefined는 기본값으로, null은 여러분이 명시한 "비어 있음"으로 취급하면, 이들의 동작이 더 이상 무작위처럼 느껴지지 않습니다.

Juno없음: null과 undefined "값 없음"을 표현하는 두 가지 방법입니다. undefined는 아무것도 설정되지 않았을 때 JavaScript가 기본으로 주는 값입니다. null은 "의도적으로 비어 있다"는 뜻으로 직접 작성하는 값입니다. 변수에 값을 준 적이 없다면 undefined가 나올 것입니다.
Juno없음: null과 undefined 둘 다 부재를 뜻하지만, 누가 그 값을 설정했는지가 다릅니다. undefined는 값을 지정하지 않고 선언한 변수처럼 저절로 나타납니다. null은 무언가를 의도적으로 비어 있다고 표시하기 위해 직접 대입하는 값입니다. 이렇게 읽으면 부재가 실수였는지 선택이었는지 알 수 있습니다.
Juno없음: null과 undefined 여기서는 관례가 큰 역할을 합니다. undefined는 JavaScript가 건네주는 부재이고, null은 여러분이 의도적으로 대입하는 부재입니다. 그래서 undefined는 "누구도 설정하지 않았다"는 신호로 버그를 가리킬 수 있는 반면, null은 의도로 읽힙니다. 이 둘을 구분해두면 나중에 비교식에서 놀라는 일이 없습니다.

typeof로 타입 확인하기

어떤 값의 타입이 확실하지 않을 때, typeof가 알려줍니다. 값 앞에 붙이면 그 타입의 이름을 담은 문자열을 반환합니다.

js
console.log(typeof "지민"); // "string"
console.log(typeof 27); // "number"
console.log(typeof true); // "boolean"

결과는 항상 텍스트이고, "number"처럼 **문자열**로 나오며, 타입 자체가 나오는 것이 아니라는 점에 주목하세요. 값을 사용하기 전에 무엇을 다루고 있는지 확인하고 싶을 때 유용합니다.

typeof는 값의 타입을 문자열로 알려줍니다. 어떤 값 앞에 붙이면 "string", "number", "boolean" 등의 결과를 얻습니다.

js
const label = "checkout";
console.log(typeof label); // "string"
console.log(typeof 24.99); // "number"
console.log(typeof false); // "boolean"
console.log(typeof undefined); // "undefined"

지금 알아둘 만한 **특이한 점**이 하나 있는데, 처음 마주치면 누구나 놀랍니다. typeof null"null"이 아니라 "object"입니다.

js
console.log(typeof null); // "object"

이는 언어에 오래전부터 있던 버그로, 고치면 기존 코드가 깨지기 때문에 결코 수정되지 않았습니다. 여러분이 뭔가를 잘못한 것이 아닙니다. typeof null은 거짓말을 한다는 점을 기억하고, 필요할 때는 null 여부를 직접 확인하세요.

typeof는 값을 받아 그 타입의 이름을 문자열로 반환합니다. 실행 시점에 "내가 지금 무엇을 다루고 있는가"를 확인하는 가장 빠른 방법입니다.

js
console.log(typeof "checkout"); // "string"
console.log(typeof 1499.5); // "number"
console.log(typeof true); // "boolean"
console.log(typeof undefined); // "undefined"

반드시 외워둬야 할 예외 하나가 있습니다. typeof null"null"이 아니라 "object"를 반환합니다.

js
console.log(typeof null); // "object"

이는 **역사적으로 굳어진 특이 사항**으로, JavaScript 최초 버전에 있던 버그가 이제는 너무 많은 기존 코드가 이 잘못된 결과에 의존하고 있어 고쳐지지 못한 것입니다. 실질적으로 이는 typeof만으로는 값이 null인지 알아낼 수 없다는 뜻이며, 대신 직접 비교로 확인해야 합니다. 이는 JavaScript의 하위 호환성 트레이드오프를 보여주는 대표적인 예로, 이미 알려진 실수라도 고치면 웹이 망가지기 때문에 그대로 남아 있는 경우입니다.

Junotypeof로 타입 확인하기 값 앞에 typeof를 붙이면 "number"처럼 문자열로 타입을 알려줍니다. 지금 다루는 값이 무엇인지 확신이 안 갈 때 가장 빠르게 확인하는 방법입니다. 결과는 항상 텍스트이므로, typeof 27은 인용부호까지 포함해 "number"를 줍니다.
Junotypeof로 타입 확인하기typeof는 타입을 문자열로 돌려주므로, 값을 사용하기 전에 확인할 수 있습니다. 함정 하나를 조심하세요. typeof null"null"이 아니라 "object"입니다. 호환성을 위해 남아 있는 버그이므로, 그 경우에는 typeof를 믿지 말고 직접 null인지 검사하세요.
Junotypeof로 타입 확인하기typeof는 실행 시점에 "이게 어떤 타입인가"를 문자열로 알려줍니다. 반드시 외워야 할 결과는 잘못된 그 하나입니다. typeof null"object"인데, 고치면 웹이 망가지기 때문에 그대로 고정된 최초 버전의 버그입니다. 따라서 null인지는 절대 확인해주지 못하니, 대신 직접 비교로 확인하세요.

타입의 더 큰 그림

지금까지 문자열, 숫자, 불리언, 그리고 nullundefined라는 일상적인 타입들을 배웠습니다. 작은 프로그램이 필요로 하는 것의 대부분을 저장하기에는 충분합니다. 이후 장들에서는 값들을 묶는 방법을 다루지만, 그런 묶음들도 결국 여러분이 이미 본 단순한 타입들로 이루어져 있습니다.

지금 얻은 성과는, 모든 값이 타입을 가지며 그 타입이 그 값으로 무엇을 할 수 있는지를 결정한다는 점을 아는 것입니다. 숫자는 더할 수 있고, 문자열은 이어붙일 수 있고, 불리언은 확인할 수 있습니다. 다음 단계로 연산자를 염두에 두세요. 이 값들을 조합하기 시작하는 지점이 바로 거기입니다.

지금까지 본 타입들, 즉 문자열, 숫자, 불리언, null, undefined는 **원시 타입(primitive type)**입니다. 단순하고 단일한 값이라는 뜻입니다. JavaScript에는 배열이나 객체처럼 여러 값의 모음을 담는 비원시 타입도 있습니다. 이런 타입들은 각각의 장에서 따로 다루며, 그때가 되면 알아둘 만한 방식으로 다르게 동작합니다.

지금 짚어둘 것 한 가지는, number가 단일 타입이라는 점입니다. JavaScript는 일부 언어처럼 정수와 소수를 별개의 타입으로 나누지 않기 때문에, 1010.5는 모두 같은 number 타입입니다. 이 덕분에 숫자에서는 모든 수치 값을 하나의 타입으로 다루면 되어 훨씬 단순하게 생각할 수 있습니다.

여기서 다룬 타입들, 문자열, 숫자, 불리언, null, undefined는 **원시 타입(primitive type)**입니다. 단일하고 독립적인 값이라는 뜻입니다. 그 외의 모든 것, 배열과 객체는 **참조 타입(reference type)**으로, 값의 모음을 담고 있으며 복사하거나 비교할 때 다르게 동작합니다. 이 차이가 많은 놀라움의 원인이 되며, 해당 타입들을 다룰 때 별도로 자세히 설명합니다.

타입 이야기를 하는 김에 몇 가지 더 짚어두겠습니다. number는 정수든 소수든 모든 수치 값을 위한 하나의 타입이므로, 따로 정수 타입을 신경 쓸 필요가 없습니다. 이는 숫자에서 다룹니다. 초반에는 거의 마주치지 않는 원시 타입이 두 가지 더 있는데, 일반적인 숫자로 표현하기에 너무 큰 정수를 위한 bigint와 고유한 키를 위한 symbol입니다. 그리고 타입은 고정되어 있지 않습니다. 특정 상황에서 JavaScript는 한 타입을 다른 타입으로 변환하는데, 이를 **강제 변환(coercion)**이라고 합니다(예를 들어 숫자와 문자열을 이어붙일 때 숫자를 문자열로 바꾸는 경우). 이는 실질적인 결과를 가져오며, 연산자에서 그 영향이 본격적으로 드러납니다.

Juno타입의 더 큰 그림 모든 값은 타입을 가지고 있고, 그 타입이 여러분이 그 값으로 무엇을 할 수 있는지 결정합니다. 숫자를 더하고, 문자열을 이어붙이고, 불리언을 확인할 수 있는 식입니다. 문자열, 숫자, 불리언, 그리고 nullundefined 같은 일상적인 타입들이 작은 프로그램이 저장하는 것 대부분을 다룹니다. 이후 장들에서는 값들을 묶지만, 그것들도 결국 이 타입들로 이루어져 있습니다.
Juno타입의 더 큰 그림 지금까지 배운 다섯 가지, 문자열, 숫자, 불리언, null, undefined는 원시 타입입니다. 단순한 단일 값이라는 뜻입니다. 배열과 객체는 나중에 배울 비원시 타입으로, 다르게 동작합니다. 알아두면 유용한 사실 하나: number1010.5 모두를 위한 단 하나의 타입이므로, 정수와 소수를 따로 신경 쓸 필요가 없습니다.
Juno타입의 더 큰 그림 원시 타입은 단일 값이고, 배열과 객체는 복사와 비교 방식이 다른 참조 타입입니다. 놀라운 일들이 대개 여기서 벌어집니다. number는 모든 수치 값을 다루고, bigintsymbol은 드문 경우를 위해 존재합니다. 타입은 서로 변환되기도 하는데 이를 강제 변환(coercion)이라 하며, 연산자에서 그 영향이 본격적으로 나타나니 염두에 두세요.

여기서부터 타입은 어디로 이어질까

여러분이 작성하는 모든 값, 다시 읽어들이는 모든 값에는 타입이 있고, 그 타입을 능숙하게 알아채는 것이 이후 모든 내용의 기반이 됩니다. 다음 장들에서는 가장 자주 다루게 될 두 타입을 깊게 파고듭니다. 텍스트를 다루는 문자열과, 계산을 위한 숫자입니다. 그다음 연산자에서는 이 타입들이 서로 만나기 시작합니다. 비교하고, 조합하고, 때로는 변환하면서 말이죠. 지금 다루는 값의 타입을 아는 것이 바로 이 과정에서 놀라지 않게 해주는 힘입니다.