1.값과 자료형 — 값에도 종류가 있다
1강에서 console.log로 숫자와 글자를 출력해 보았습니다. 이렇게 프로그램이 다루는 하나하나의 데이터를 값이라고 하고, 값의 종류를 자료형이라고 합니다. 사람은 '3'이라는 글자와 3이라는 수를 문맥으로 구분하지만, 컴퓨터는 값마다 종류를 붙여 두고 그 종류에 따라 할 수 있는 일을 정합니다. 수는 더하고 곱할 수 있고, 글자는 이어 붙이거나 길이를 셀 수 있습니다.
JavaScript에서 가장 자주 쓰는 기본 자료형은 다섯 가지입니다. 숫자(number)는 정수와 소수를 구분하지 않고 모두 하나의 종류로 다룹니다. 문자열(string)은 따옴표로 감싼 글자들입니다. 불리언(boolean)은 참(true)과 거짓(false) 둘뿐인 값으로, 3강의 조건문에서 핵심 역할을 합니다. undefined는 '아직 값이 정해지지 않음', null은 '값이 없음을 일부러 표시함'이라는 뜻입니다. 이 밖에도 아주 큰 정수를 위한 bigint, 고유한 표식인 symbol이 있지만 이 과정에서는 거의 쓰지 않습니다.
값의 종류는 typeof 연산자로 확인할 수 있습니다. 결과는 종류 이름을 담은 문자열입니다. 한 가지 오래된 예외가 있는데, typeof null은 "null"이 아니라 "object"라고 나옵니다. JavaScript 초기 설계의 흔적으로, 이제 와서 바꾸면 기존 웹 페이지가 깨지기 때문에 그대로 남아 있습니다. 그래서 어떤 값이 null인지 확인할 때는 typeof 대신 3강에서 배울 === null 비교를 씁니다.
console.log(typeof 42, typeof 3.14);
console.log(typeof "안녕", typeof "42");
console.log(typeof true, typeof undefined);
console.log(typeof null); // 오래된 예외number number string string boolean undefined object
| 자료형 | 예 | `typeof` 결과 | 쓰임 |
|---|---|---|---|
| 숫자 | 42, 3.14, -7 | "number" | 개수·금액·점수 같은 계산 |
| 문자열 | "민수", '42' | "string" | 이름·문장·전화번호처럼 계산하지 않는 글자 |
| 불리언 | true, false | "boolean" | 예/아니요, 조건 판단 |
undefined | undefined | "undefined" | 아직 값을 넣지 않은 상태 |
null | null | "object"(예외) | 값이 없음을 일부러 표시 |
2.변수 — `let`과 `const`로 이름표 붙이기
같은 값을 여러 번 쓰거나 계산 결과를 잠시 보관하려면 값에 이름을 붙여야 합니다. 이 이름을 변수라고 합니다. 변수는 상자라기보다 값에 붙이는 이름표에 가깝습니다. const price = 1200;이라고 쓰면 1200이라는 값에 price라는 이름표가 붙고, 그 뒤로는 price라고만 써도 1200을 가리킵니다. 여기서 =는 수학의 '같다'가 아니라 '오른쪽 값을 왼쪽 이름에 넣는다'는 뜻입니다.
변수를 만드는 방법은 두 가지입니다. const는 한 번 정하면 다른 값을 다시 넣을 수 없는 변수이고, let은 나중에 다른 값으로 바꿀 수 있는 변수입니다. 기본은 const로 쓰고, 값이 바뀌어야 하는 경우(합계를 누적하거나 개수를 셀 때 등)에만 let을 쓰는 것이 좋은 습관입니다. 이렇게 하면 '이 값은 바뀌지 않는다'는 사실이 코드에 드러나서 읽는 사람이 안심할 수 있고, 실수로 덮어쓰면 바로 오류로 알려 줍니다. 옛 코드에서 보이는 var는 규칙이 헷갈리는 옛 방식이라 새 코드에서는 쓰지 않습니다.
이름은 무엇을 담았는지 알 수 있게 짓습니다. a, x2보다 price, totalCount가 훨씬 읽기 쉽습니다. JavaScript에서는 여러 단어를 이을 때 두 번째 단어부터 첫 글자를 대문자로 쓰는 방식(totalPrice)을 흔히 씁니다. 이름은 숫자로 시작할 수 없고, 띄어쓰기를 넣을 수 없으며, let·if 같은 예약어는 쓸 수 없습니다. 대소문자를 구별하므로 price와 Price는 서로 다른 변수입니다.
const, 바뀌는 값은 letconst price = 1200;
const count = 3;
const total = price * count;
console.log("합계:", total);
let visits = 0;
visits = visits + 1;
visits = visits + 1;
console.log("방문 수:", visits);합계: 3600 방문 수: 2
const 변수에 다시 넣으면 3행에서 오류로 멈춥니다const rate = 0.05;
console.log("이율:", rate);
rate = 0.07;
console.log("바뀐 이율:", rate);이율: 0.05
TypeError: Assignment to constant variable.undefined입니다let memo;
console.log(memo);
memo = "장보기";
console.log(memo);undefined 장보기
visits = visits + 1은 수학으로 보면 말이 안 되지만, 코드에서는 '지금 visits 값에 1을 더한 결과를 다시 visits에 넣는다'는 뜻입니다. 줄여서 visits += 1이라고도 씁니다. 4강의 반복문에서 이 '누적' 패턴을 계속 씁니다.3.연산자 — 계산하고 이어 붙이기
숫자에는 사칙연산 +, -, *, / 외에 나머지를 구하는 %와 거듭제곱 **가 있습니다. %는 생각보다 자주 씁니다. 어떤 수를 2로 나눈 나머지가 0이면 짝수이고, 분 단위 시간을 60으로 나눈 몫과 나머지로 '몇 시간 몇 분'을 만들 수 있습니다. 계산 순서는 수학과 같아서 곱하기·나누기가 더하기·빼기보다 먼저이고, 헷갈리면 괄호를 쳐서 의도를 분명히 하는 것이 좋습니다.
나누기 결과가 정수가 아니어도 JavaScript는 소수로 답합니다. 7 / 2는 3.5입니다. 몫만 필요하면 Math.floor로 소수점 아래를 버리고, 반올림은 Math.round, 올림은 Math.ceil을 씁니다. 0으로 나누면 오류가 나는 대신 Infinity(무한대)가 나오고, 숫자로 바꿀 수 없는 계산을 하면 '숫자가 아님'을 뜻하는 NaN이 나옵니다. NaN은 이름과 달리 typeof가 "number"인 특별한 숫자 값이라는 점도 기억해 두세요.
+는 문자열에도 쓰입니다. 두 문자열을 +로 더하면 이어 붙입니다. "안녕" + "하세요"는 "안녕하세요"가 됩니다. 문자열 속에 변수 값을 넣을 때는 백틱(키보드 숫자 1 왼쪽 키)으로 감싸고 그 안에 달러 기호와 중괄호로 변수를 넣는 '템플릿 문자열'이 편합니다. 생김새는 아래 코드 예에서 직접 확인하세요. 7강에서 문자열을 더 자세히 다룹니다.
%는 나머지, **는 거듭제곱console.log(7 + 2, 7 - 2, 7 * 2, 7 / 2);
console.log(7 % 2, 2 ** 10);
console.log(Math.floor(7 / 2), Math.round(2.5));
console.log(Math.ceil(2.1), 1 / 0);9 5 14 3.5 1 1024 3 3 3 Infinity
const minutes = 135;
const h = Math.floor(minutes / 60);
const m = minutes % 60;
console.log(h + "시간 " + m + "분");
console.log(`${h}시간 ${m}분`);2시간 15분 2시간 15분
4.형 변환의 함정 — `"1" + 2`는 왜 `"12"`일까
JavaScript는 종류가 다른 값을 섞어 계산하면 오류를 내는 대신 한쪽을 알아서 바꿔 계산합니다. 이것을 암묵적 형 변환이라고 합니다. 편리할 때도 있지만 초보자 실수의 큰 원인입니다. 가장 유명한 예가 "1" + 2입니다. +의 한쪽이 문자열이면 JavaScript는 '이어 붙이기'로 해석해 숫자 2를 문자열 "2"로 바꾸고, 결과는 "12"가 됩니다.
그런데 "5" - 2는 3입니다. -, *, /는 문자열에 쓸 수 없는 연산이라 이번에는 문자열을 숫자로 바꿔 계산하기 때문입니다. 같은 문자열과 숫자인데 연산자에 따라 결과가 문자열이 되기도 하고 숫자가 되기도 하니 헷갈릴 수밖에 없습니다. 이 문제는 실제로 자주 일어납니다. 입력 칸, 텍스트 파일, CSV에서 읽은 값은 숫자처럼 보여도 대부분 문자열이어서, 그대로 더하면 합계 대신 글자가 줄줄이 이어진 결과가 나옵니다(9강).
해결책은 계산하기 전에 직접 숫자로 바꾸는 것입니다. 이것을 명시적 형 변환이라고 합니다. Number("12")는 숫자 12가 되고, Number("12원")처럼 숫자로 읽을 수 없는 글자가 섞이면 NaN이 됩니다. 반대로 숫자를 문자열로 바꿀 때는 String(12)를 씁니다. 결과가 이상하면 먼저 typeof로 값의 종류를 찍어 보는 습관을 들이세요. 8강의 디버깅도 이렇게 '값이 내가 생각한 종류인가'를 확인하는 데서 출발합니다.
+의 한쪽이 문자열이면 이어 붙이기가 됩니다console.log("1" + 2);
console.log(1 + 2 + "3");
console.log("5" - 2, "5" * "2");
console.log(typeof ("1" + 2));12 33 3 10 string
Number로 바꾼 뒤 계산합니다const a = "3000";
const b = "4500";
console.log(a + b);
console.log(Number(a) + Number(b));
console.log(Number("12원"), Number(""));
console.log(String(12) + String(3));30004500 7500 NaN 0 123
- 더했는데 결과가 이상하게 길어졌다면 문자열끼리 이어 붙은 것이 아닌지 의심한다
- 외부에서 읽은 값(입력·파일·표)은 계산 전에
Number로 바꾼다 Number의 결과가NaN이면 숫자가 아닌 글자(단위, 쉼표 등)가 섞인 것이다- 빈 문자열
""은Number로 바꾸면0이 된다는 점에 주의한다 — 빈 칸을 0으로 셀지 따로 처리할지 정해야 한다
5.`0.1 + 0.2`는 `0.3`이 아니다
실습장에서 0.1 + 0.2를 출력해 보면 0.30000000000000004가 나옵니다. JavaScript가 계산을 못하는 것이 아닙니다. 컴퓨터는 수를 2진법으로 저장하는데, 10진법의 0.1은 2진법으로 끝없이 이어지는 소수라서 정해진 칸에 담을 때 아주 조금 잘립니다. 10진법에서 1/3을 0.333…으로 끝까지 적을 수 없는 것과 같은 이치입니다. 이 방식(부동소수점)은 거의 모든 프로그래밍 언어가 같은 표준을 따르므로 다른 언어에서도 똑같이 일어납니다.
오차는 아주 작아서 대부분의 계산에서는 문제가 되지 않지만, 두 가지 경우에는 조심해야 합니다. 첫째는 같은지 비교할 때입니다. 0.1 + 0.2 === 0.3은 false입니다. 둘째는 돈처럼 1원도 틀리면 안 되는 계산입니다. 소수를 여러 번 더하고 곱하다 보면 작은 오차가 쌓여 표시에 드러날 수 있습니다.
흔히 쓰는 해결책은 세 가지입니다. 원·센트처럼 가장 작은 단위의 정수로 바꿔 계산하면, 정수끼리 더하고 빼고 곱하는 동안에는 오차가 생기지 않습니다(아주 큰 수가 아닌 한). 나눗셈이 들어가면 마지막에 한 번만 반올림합니다. 화면에 보일 때만 toFixed로 자릿수를 맞추거나 Math.round로 반올림합니다. 비교할 때는 두 값의 차이가 아주 작은지 보는 방법을 씁니다. 실습장의 채점기도 소수 결과는 아주 작은 차이를 같다고 봅니다. 단, toFixed의 결과는 숫자가 아니라 문자열이라는 점을 잊지 마세요.
toFixed는 문자열을 돌려줍니다console.log(0.1 + 0.2);
console.log(0.1 + 0.2 === 0.3);
console.log((0.1 + 0.2).toFixed(2));
console.log(typeof (0.1 + 0.2).toFixed(2));0.30000000000000004 false 0.30 string
// 1.10달러 + 2.20달러를 센트(정수)로 계산
const cents = 110 + 220;
console.log(cents / 100);
console.log(1.1 + 2.2);3.3 3.3000000000000003
const total = 1200 * 3;
const pay = Math.round(total * 90 / 100);
console.log("결제 금액:", pay);결제 금액: 3240
- 1단계 합계는 정수 계산이라 안전합니다: 1200 * 3 = 3600.
- 2단계 할인율을 소수(0.9)로 곱하지 않고 정수 곱셈과 나눗셈으로 바꿉니다: 3600 * 90 / 100 = 3240.
- 3단계 나누어떨어지지 않을 수 있으니 원 단위로
Math.round(또는 정책에 따라Math.floor)를 씌웁니다. - 검산: 3600의 10%는 360이므로 3600 − 360 = 3240원으로 같습니다.
6.`null`과 `undefined` — 비어 있음의 두 얼굴
JavaScript에는 '값이 없음'을 나타내는 값이 두 개 있습니다. undefined는 대개 JavaScript가 스스로 넣는 값입니다. 변수를 만들고 값을 넣지 않았을 때, 객체에 없는 속성을 읽을 때(6강), 함수가 아무것도 돌려주지 않을 때(5강) 나옵니다. null은 사람이 일부러 넣는 값으로, '여기는 비어 있다는 것을 알고 있다'는 표시입니다. 예를 들어 아직 입력되지 않은 전화번호 칸에 null을 넣어 두는 식입니다.
둘 다 계산에 쓰면 이상한 결과가 나옵니다. null은 숫자 계산에서 0처럼 취급되어 null + 1이 1이 되고, undefined는 숫자로 바꿀 수 없어 undefined + 1이 NaN이 됩니다. 이런 결과는 오류 메시지 없이 조용히 퍼지기 때문에 더 위험합니다. 합계가 NaN으로 나온다면 계산 중 어딘가에 undefined가 섞였다는 신호로 읽으면 됩니다.
더 큰 문제는 비어 있는 값에서 무언가를 꺼내려 할 때입니다. null이나 undefined의 속성을 읽으려 하면 TypeError로 멈춥니다. AI가 써 준 코드에서도 자주 보이는 오류로, '자료가 비어 있을 때'를 처리하지 않은 것이 원인입니다. 3강에서 이런 경우를 조건문으로 미리 걸러 내는 법을 배웁니다.
console.log(null + 1, undefined + 1);
let phone = null;
console.log("전화번호:", phone);
console.log(phone.length);1 NaN
전화번호: null
TypeError: Cannot read properties of null (reading 'length')📌 핵심 정리
- 기본 자료형은 숫자·문자열·불리언·
undefined·null이고typeof로 확인한다(typeof null은 예외로"object") - 기본은
const, 값이 바뀌어야 할 때만let을 쓰고var는 쓰지 않는다 +는 한쪽이 문자열이면 이어 붙이기가 된다 — 읽어 온 값은Number로 바꾼 뒤 계산한다0.1 + 0.2의 오차는 2진법 저장 때문이며, 돈은 정수 단위로 계산하고 표시할 때 반올림한다NaN이나TypeError가 보이면 계산 중에undefined·null이 섞이지 않았는지 의심한다
🧪 코드 실습
함수 안의 빈칸을 채우는 실습입니다. 함수는 5강에서 자세히 배우니, 지금은 '괄호 안 이름으로 값을 받고 return 뒤의 값을 돌려준다'는 것만 알면 됩니다.
코드는 이 브라우저 안의 격리된 공간에서만 실행되고 서버로 보내지 않습니다. 네트워크에는 접속할 수 없고, 2초가 넘으면 멈춥니다. 고친 코드는 이 브라우저에만 저장됩니다. Ctrl+Enter(⌘+Enter)로 실행하고, Tab 키는 공백 두 칸입니다(Esc 다음 Tab 은 다음 칸으로 이동).
자바스크립트가 꺼져 있어 실행할 수는 없지만, 문제와 처음 코드, 자동 검사 내용, 예시 답안은 그대로 읽을 수 있습니다.
1합계 구하기
totalPrice(price, count)는 가격 price와 개수 count(둘 다 숫자)를 받아 합계를 돌려줍니다. 개수가 0이면 0입니다.
totalPrice(1200, 3)기대값3600totalPrice(2500, 1)기대값2500totalPrice(990, 0)기대값0totalPrice(0, 5)기대값0
💡 힌트
곱하기는 *입니다. const total = price * count;
예시 답안 보기
function totalPrice(price, count) {
const total = price * count;
return total;
}
2문자열 숫자 더하기
addStrings(a, b)는 숫자가 적힌 문자열 두 개(예: "3000", "4500")를 받아 두 수의 합을 숫자로 돌려줍니다. 그냥 a + b를 하면 이어 붙여지니 주의하세요.
addStrings("3000", "4500")기대값7500addStrings("1", "2")기대값3addStrings("0", "0")기대값0addStrings("-5", "2.5")기대값-2.5
💡 힌트
Number(a)는 문자열 a를 숫자로 바꿉니다.
예시 답안 보기
function addStrings(a, b) {
return Number(a) + Number(b);
}
3자료형 이름 알려 주기
typeName(v)는 값 v의 자료형 이름을 문자열로 돌려줍니다. typeof와 같지만 null일 때만 "object" 대신 "null"을 돌려주세요.
typeName(42)기대값"number"typeName("42")기대값"string"typeName(true)기대값"boolean"typeName(null)기대값"null"typeName("")기대값"string"
💡 힌트
if (v === null) { return "null"; }을 return typeof v; 앞에 넣습니다. if는 3강에서 자세히 배웁니다.
예시 답안 보기
function typeName(v) {
if (v === null) {
return "null";
}
return typeof v;
}
4더치페이 금액
splitBill(total, people)는 총액 total원을 people명이 나눠 낼 때 한 사람이 낼 금액을 돌려줍니다. 모자라지 않게 10원 단위로 올림하세요. 예: 10000원을 3명이면 3333.33…원 → 3340원.
splitBill(10000, 3)기대값3340splitBill(9000, 3)기대값3000splitBill(25010, 2)기대값12510splitBill(0, 4)기대값0splitBill(1, 1)기대값10
💡 힌트
10으로 나눈 뒤 Math.ceil로 올리고 다시 10을 곱합니다. 이미 10원 단위면 그대로 남습니다.
예시 답안 보기
function splitBill(total, people) {
const each = total / people;
return Math.ceil(each / 10) * 10;
}
🤖 AI에게 이렇게 물어보세요
복사해서 [ ] 부분을 내 상황으로 바꿔 쓰세요. 답을 그대로 믿지 말고 본문과 비교해 확인하세요.
계산 결과가 이상하게 나올 때
아래 JavaScript 코드의 결과가 [기대한 값]이 아니라 [실제 값]으로 나와. 각 변수의 자료형(`typeof`)이 줄마다 어떻게 되는지 표로 보여 주고, 형 변환이 일어난 곳을 짚어 줘. 고친 코드는 마지막에 보여 줘. 코드: [코드 붙여 넣기]
형 변환 감각을 연습하고 싶을 때
`"1" + 2`, `"5" - 2`, `null + 1` 같은 JavaScript 형 변환 문제 8개를 만들어 줘. 답은 숨기고 내가 예측한 값을 보내면 맞았는지와 그 까닭을 알려 줘. 마지막 2문제는 실제 업무(표에서 읽은 금액 더하기)처럼 만들어 줘.
돈 계산 코드를 검토할 때
다음 JavaScript 금액 계산 코드에 소수 오차나 반올림 문제가 생길 곳이 있는지 검토해 줘. 원 단위 정수로 계산하는 방식으로 바꾼다면 어떻게 되는지 보여 주고, 반올림·버림 중 무엇을 썼는지 주석으로 밝혀 줘. 코드: [코드 붙여 넣기]
🧰 관련 도구
이 강의에서 다룬 JSON·정규식·텍스트를 바로 확인하고 다듬어 볼 수 있는 도구입니다. 실제 개인정보나 비밀번호는 붙여 넣지 마세요.
- MDN Web Docs — JavaScript 안내서(Guide)의 문법과 자료형, 표현식과 연산자
- MDN Web Docs — typeof, Number, 부동소수점 수에 관한 참고 문서
- IEEE 754 부동소수점 표준에 관한 일반적 설명
학습 목표를 모두 이뤘다면 완료를 눌러 진도에 기록하세요.
이 브라우저에서는 저장할 수 없어 이 화면에서만 표시됩니다.