자바스크립트의 기본 문법에 대하여 공부해보겠다
간단하게 개념을 정리하고 내가 공부한 코드 위주로 진행하고자 한다.
변수란 데이터를 저장하는 공간
변수를 선언하는 세 가지 방식 var,let,const를 비교해보자
var는 이전 방식으로 문제점을 가지고있다.// 1. 중복 선언 가능 (위험!)
var name = '홍길동';
var name = '김철수'; // 에러 없음
console.log(name); // 김철수
// 2. 함수 스코프 (나중에 자세히 배움)
if (true) {
var message = '안녕';
}
console.log(message); // 안녕 (밖에서도 접근 가능)
// 3. 호이스팅 문제
console.log(x); // undefined (에러가 아님!)
var x = 10;
따라서 최근에는(modern) let과 const를 사용한다.
// let으로 변수 선언
let name = '홍길동';
let age = 25;
console.log(name); // 홍길동
console.log(age); // 25
// 값 변경 가능
age = 26;
age = 27;
console.log(age); // 27
❗중복 선언 불가, 블록 스코프 (블록 밖에서는 접근 불가)
let score = 100;
let score = 90; // ❌ SyntaxError: Identifier 'score' has already been declared
// 값 변경은 가능
score = 90; // ✅
if (true) {
let message = '안녕';
console.log(message); // 안녕
}
console.log(message); // ❌ ReferenceError: message is not defined
// 블록 밖에서는 접근 불가
// const로 상수 선언
const PI = 3.14159;
const MAX_SIZE = 100;
const API_KEY = 'abc123xyz';
console.log(PI); // 3.14159
값 변경 불가, 선언과 동시에 초기화 필수
const birthYear = 1990;
birthYear = 1995; // ❌ TypeError: Assignment to constant variable.
// 재선언도 불가
const name = '홍길동';
const name = '김철수'; // ❌ SyntaxError
const age; // ❌ SyntaxError: Missing initializer in const declaration
const age = 25; // ✅
❗주의 : 객체와 배열은 내용 변경 가능하다.
// const로 선언해도 객체/배열의 내용은 변경 가능
const person = {
name: '홍길동',
age: 25
};
person.age = 26; // ✅ 가능
console.log(person); // {name: '홍길동', age: 26}
person = {}; // ❌ 불가능 (재할당)
const numbers = [1, 2, 3];
numbers.push(4); // ✅ 가능
console.log(numbers); // [1, 2, 3, 4]
numbers = [5, 6]; // ❌ 불가능 (재할당)
| 특징 | var | let | const |
|---|---|---|---|
| 재선언 | 가능 | 불가능 | 불가능 |
| 재할당 | 가능 | 가능 | 불가능 |
| 스코프 | 함수 | 블록 | 블록 |
| 호이스팅 | 있음 | 있음(TDZ) | 있음(TDZ) |
| 사용 권장 | ❌ | ✅ | ✅✅ |
const > let > var 순으로 사용해보자
Type은 쉽게 말해 데이터의 종류다.
변수라는 상자에 넣을 수 있는 것들 :
❗undefined vs null
undefined는 값이 할당되지 않은 상태이다.
null은 '값이 없음'을 표현한 것이다.
이 둘의 가장 큰 차이는 의도적이냐 의도적이지 않느냐로 볼 수 있다.
의도적 : null
자동으로 할당 : undefined
값 자체가 저장 됨
자바스크립트라는 언어를 이해함에 있어 참조타입은 중요한 개념이다.
// 데이터 타입 확인
console.log(typeof 10); // number
console.log(typeof '안녕'); // string
console.log(typeof true); // boolean
console.log(typeof undefined); // undefined
console.log(typeof null); // object (버그!)
console.log(typeof [1, 2, 3]); // object
console.log(typeof {name: '홍길동'}); // object
console.log(typeof function(){}); // function
❗null도 object라 나오는 것을 볼 수 있다. 아주 오래된 버그니 그냥 받아들이자
null 체크 방법 :
let value = null;
console.log(value == null); // true
자바스크립트에서 사용되는 기본 연산자를 정리해보겠다.
너무 많아서 표로 정리하겠다
| 연산자 | 의미 | 예시 | 결과 |
|---|---|---|---|
+ | 덧셈 | 10 + 20 | 30 |
- | 뺄셈 | 30 - 10 | 20 |
* | 곱셈 | 5 * 6 | 30 |
/ | 나눗셈 | 20 / 4 | 5 |
% | 나머지 | 10 % 3 | 1 |
** | 거듭제곱 | 2 ** 3 | 8 |
JavaScript의 연산 순서는 수학과 동일하다.
| 코드 | 실행 순서 | 결과 |
|---|---|---|
10 + 5 * 2 | 곱셈 → 덧셈 | 20 |
(10 + 5) * 2 | 괄호 → 곱셈 | 30 |
👉 *, /, %, ** 가 +, - 보다 우선
👉 괄호 ()를 사용하면 우선순위를 직접 지정할 수 있다.
| 예시 코드 | 결과 | 설명 |
|---|---|---|
'홍' + '길동' | '홍길동' | 문자열 + 문자열 |
'안녕하세요, ' + '홍길동' + '님!' | '안녕하세요, 홍길동님!' | 여러 문자열 연결 |
'나이: ' + 25 | '나이: 25' | 문자열 + 숫자 → 문자열 변환 |
'10' + 20 | '1020' | 숫자도 문자열로 변환됨 |
👉 + 연산자는 숫자 연산과 문자열 연결 둘 다 가능
👉 문자열이 하나라도 포함되면 결과는 문자열이 된다.
| 방식 | 코드 | 결과 |
|---|---|---|
+ 사용 | name + '님은 ' + age + '세입니다.' | 홍길동님은 25세입니다. |
| 템플릿 리터럴 | `${name}님은 ${age}세입니다.` | 홍길동님은 25세입니다. |
✔ 장점
| 연산자 | 의미 | 예시 | 결과 |
|---|---|---|---|
++ | 1 증가 | count++ | 값이 1 증가 |
-- | 1 감소 | score-- | 값이 1 감소 |
| 종류 | 코드 | 설명 | 결과 |
|---|---|---|---|
| 후위 증가 | let b = a++; | 먼저 사용 → 나중에 증가 | b는 기존값 |
| 전위 증가 | let y = ++x; | 먼저 증가 → 나중에 사용 | y는 증가된 값 |
let a = 5;
let b = a++;
// a = 6, b = 5
let x = 5;
let y = ++x;
// x = 6, y = 6
👉 실무에서는 혼동을 줄이기 위해 단독 사용을 권장하는 경우가 많다.
| 연산자 | 의미 | 예시 |
|---|---|---|
= | 값 할당 | let x = 10; |
| 연산자 | 의미 | 풀어쓴 형태 | 예시 결과 |
|---|---|---|---|
+= | 더해서 할당 | x = x + 5 | 15 |
-= | 빼서 할당 | x = x - 3 | 12 |
*= | 곱해서 할당 | x = x * 2 | 24 |
/= | 나눠서 할당 | x = x / 4 | 6 |
%= | 나머지 할당 | x = x % 4 | 2 |
산술 연산자는 숫자 계산에 사용된다.
+는 문자열 연결도 가능하다.
문자열이 포함되면 자동으로 문자열 변환이 일어난다.
템플릿 리터럴을 사용하는 것이 가장 깔끔하다.
++, --는 전위/후위 차이를 반드시 이해해야 한다.
복합 할당 연산자는 코드를 간결하게 만들어준다.
이제 실습을 해보자
- 두 숫자를 변수에 저장
- 덧셈, 뺄셈, 곱셈, 나눗셈 결과 계산
- 결과를 콘솔에 출력
// 시작 코드
// calculator.js
// TODO: 두 숫자 변수 선언
// 힌트: const num1 = ...
const num1 = 6;
const num2 = 8;
// TODO: 덧셈 결과 계산 및 출력
// 힌트: const sum = num1 + num2
const sum = num1 + num2;
console.log(sum); // 14
// TODO: 뺄셈 결과 계산 및 출력
const subtraction = num1 - num2;
console.log(subtraction); // -2
// TODO: 곱셈 결과 계산 및 출력
const multiplication = num1 * num2;
console.log(multiplication);// 48
// TODO: 나눗셈 결과 계산 및 출력
const division = num1 / num2;
console.log(division); // 0.75
// TODO: 나머지 계산 및 출력
const rem = num1 % num2;
console.log(rem); // 6
// **도전 과제:**
num3 = 10
// 1. 복합 계산 추가 (예: (a + b) * c)
const hard = (num1 + num2) * num3;
console.log(hard) // 140
// 2. 템플릿 리터럴로 출력 형식 개선
console.log(`${num1} + ${num2} = ${sum}`) // 6 + 8 = 14
// 3. 다른 숫자로도 테스트
newNum1 = 20;
newNum2 = 5;
const newMultiplication = newNum1 * newNum2;
console.log(`${newNum1} * ${newNum2} = ${newMultiplication}`) // 20 * 5 = 100
템플릿 리터럴이 처음에 무엇인지 몰랐다.
자바스크립트에서 문자열을 입력하는 선진적인 방식
백틱(` `)내부에 문자열을 입력하고, 변수는 (${})내부에 넣어 사용한다
console.log(`${newNum1} * ${newNum2} = ${newMultiplication}`) // 20 * 5 = 100
기존 방식보다 간결해보여서 자주 사용해서 익숙해져야겠다.
== : 동등 연산자 - 값만 비교=== : 일치 연산자 - 값과 타입 모두 비교// == (동등 연산자) - 값만 비교
console.log(10 == 10); // true
console.log(10 == '10'); // true (타입 무시)
console.log(1 == true); // true (타입 변환)
console.log(0 == false); // true (타입 변환)
// === (일치 연산자) - 값과 타입 모두 비교 (권장!)
console.log(10 === 10); // true
console.log(10 === '10'); // false (타입 다름)
console.log(1 === true); // false (타입 다름)
console.log(0 === false); // false (타입 다름)
✔️권장사항
// ❌ == 사용하지 마세요
if (age == '18') { }
// ✅ === 사용하세요
if (age === 18) { }
간단하게 표로 정리하겠다.
| 연산자 | 이름 | 비교 기준 | 타입 비교 여부 | 예시 | 결과 |
|---|---|---|---|---|---|
!= | 부등 연산자 | 값만 비교 (자동 형변환 발생) | ❌ 타입은 비교하지 않음 | 10 != '10' | false |
!= | 부등 연산자 | 값 비교 | ❌ | 10 != 20 | true |
!== | 불일치 연산자 | 값과 타입 모두 비교 | ✅ 타입까지 비교 | 10 !== '10' | true |
!== | 불일치 연산자 | 값과 타입 비교 | ✅ | 10 !== 20 | true |
| 연산자 | 의미 | 설명 | 예시 | 결과 |
|---|---|---|---|---|
> | 초과 | 왼쪽 값이 오른쪽 값보다 큰지 비교 | 10 > 5 | true |
< | 미만 | 왼쪽 값이 오른쪽 값보다 작은지 비교 | 10 < 5 | false |
>= | 이상 | 왼쪽 값이 오른쪽 값보다 크거나 같은지 비교 | 10 >= 10 | true |
<= | 이하 | 왼쪽 값이 오른쪽 값보다 작거나 같은지 비교 | 10 <= 9 | false |
조건이 true일 때만 실행된다.
if (조건) {
// 실행 코드
}
✔ 단일 조건 판단에 사용
조건이 true / false일 때를 나눠 실행한다.
if (조건) {
// true일 때
} else {
// false일 때
}
✔ 두 가지 경우로 나눌 때 사용
여러 조건을 순서대로 비교할 때 사용한다.
if (조건1) {
} else if (조건2) {
} else {
}
✔ 위에서부터 순서대로 검사
✔ 처음 true가 되는 조건만 실행
if문 안에 또 다른 if문을 사용하는 구조.
if (조건1) {
if (조건2) {
}
}
✔ 조건이 단계적으로 필요한 경우 사용
✔ 가독성이 떨어질 수 있으니 과도한 중첩은 지양
하나의 값에 대해 여러 경우를 비교할 때 사용한다.
switch (값) {
case 값1:
break;
case 값2:
break;
default:
}
✔ 정확한 값 비교에 적합
✔ break가 없으면 아래 case까지 계속 실행됨 (fall-through)
| 구분 | if | switch |
|---|---|---|
| 범위 비교 | ✅ 가능 | ❌ 불가능 |
| 복잡한 조건 | ✅ 가능 | ❌ 제한적 |
| 명확한 값 비교 | 가능 | ✅ 더 깔끔 |
| 가독성 | 조건 많으면 복잡 | 값 비교 시 깔끔 |
// grade.js
const score = 85;
// TODO: if-else 문으로 학점 계산
if (score >= 90){
console.log(`점수: + ${score}`);
console.log("학점: A");
} else if (score >= 80){
console.log(`점수: + ${score}`);
console.log("학점: B");
} else if (score >= 70){
console.log(`점수: + ${score}`);
console.log("학점: C");
} else if (score >= 60){
console.log(`점수: + ${score}`);
console.log("학점: D");
} else {
console.log(`점수: + ${score}`);
console.log("학점: F");
}
// TODO: switch 문으로도 구현해보기 (도전!)
switch (true) {
case score >= 90:
console.log(`점수: + ${score}`);
console.log("학점: A");
break;
case score >= 80:
console.log(`점수: + ${score}`);
console.log("학점: B");
break;
case score >= 70:
console.log(`점수: + ${score}`);
console.log("학점: C");
break;
case score >= 60:
console.log(`점수: + ${score}`);
console.log("학점: D");
break;
default :
console.log(`점수: + ${score}`);
console.log("학점: F");
break;
}
// 결과
점수: + 85
학점: B
점수: + 85
학점: B
다른 숫자로도 잘 나온다.
switch(true)에서 ture는 1 이상 모든 수가 가능하다. 이걸 truthy라고 하고, 반대로 0 은 falsy 즉, 0이다.
이건 이후에 다뤄보겠다.
if - else 문 내부에서 예를 들어 B 학점과 같은 경우 score < 90 && score >= 80이라고 하지 않더라도 이미 위에서 score >= 90이 지나왔기 때문에, score < 90을 생략해도 된다.
따로 break를 걸어주지 않더라도, 조건에 만족하면 알아서 멈추는 것이다.
switch 문에서는 일일이 console.log로 찍는 것이 아닌 grade라는 변수를 선언해서 학점을 넣고, switch 문 밖에서 console.log로 찍는 것이 더 깔끔했을 것 같다.
// 수정 코드
let grade;
switch (true) {
case score >= 90:
grade = "A";
break;
case score >= 80:
grade = "B";
break;
case score >= 70:
grade = "C";
break;
case score >= 60:
grade = "D";
break;
default:
grade = "F";
}
console.log(`점수: ${score}`);
console.log(`학점: ${grade}`);
grade는 값이 변하기에 const가 아닌 let을 사용해서 선언했다.
const로 선언하면 아래와 같은 오류가 발생한다.
