웹 개발 배우기 4편 - 자바스크립트 조건문, 불리언과 if문으로 논리 마스터하기
‘웹 개발 배우기’ 시리즈의 네 번째 시간입니다.
이번 챕터에서는 특정 조건이 만족될 때만 코드를 실행하는 아주 중요한 도구들에 대해 알아볼 텐데요.
바로 ‘불리언(Boolean)’, ‘비교’, 그리고 ‘if 문’입니다.
새로운 데이터 타입, 불리언
이 두 타입은 0, -5, 7.1처럼 수많은 값을 가질 수 있습니다.
하지만 불리언은 좀 다른데요.
이 데이터 타입의 값은 true
(참)와 false
(거짓), 딱 두 가지뿐입니다.
보통 예/아니오로 답할 수 있는 질문에 대한 결과로 이 값들이 반환되거든요.
예를 들어 Number.isInteger()
메소드는 주어진 값이 정수인지 아닌지 알려줍니다.
> Number.isInteger(1)
true
> Number.isInteger(5.0)
true
> Number.isInteger(5.1)
false
문자열에는 특정 문자열로 시작하는지 알려주는 .startsWith()
메소드가 있는데요.
> '잘 지내세요?'.startsWith('잘')
true
> '잘 지내세요?'.startsWith('왜')
false
배열에는 특정 요소를 포함하고 있는지 확인하는 .includes()
메소드도 있습니다.
> ['a', 'b', 'c'].includes('a')
true
> ['a', 'b', 'c'].includes('x')
false
원시 값과 객체, 자바스크립트 값의 두 종류
자바스크립트는 값을 크게 두 종류로 구분합니다.
하나는 undefined
, 불리언, 숫자, 문자열 같은 ‘원시 값(primitive value)‘이고, 다른 하나는 배열 같은 ‘객체(object)‘입니다.
원시 값은 단일 값을 가지며, 절대 변경할 수 없는 ‘불변성’을 특징으로 하는데요.
반면 객체는 여러 값을 담을 수 있으며, 생성된 후에도 내용을 바꿀 수 있는 ‘가변성’을 가집니다.
객체를 변수에 할당하면 그 객체가 변수 안에 그대로 저장되는 것처럼 보이는데요.
하지만 실제 내부 동작 방식은 조금 다릅니다.
객체는 ‘힙(heap)‘이라는 별도의 메모리 공간에 저장되고, 변수에는 그 객체를 가리키는 고유한 ‘주소(identity)‘만 담기게 되거든요.
이 때문에 두 변수에 같은 객체를 할당하면, 두 변수는 메모리상의 동일한 객체를 ‘공유’하게 됩니다.
const arr1 = ["a", "b", "c"];
const arr2 = arr1; // 배열 자체가 아닌 주소를 복사
이제 arr1
과 arr2
는 같은 배열을 가리키고 있는 건데요.
그래서 arr1
을 통해 배열을 수정하면 arr2
에도 똑같이 반영됩니다.
> arr1[1] = 'x';
> arr1
[ 'a', 'x', 'c' ]
> arr2
[ 'a', 'x', 'c' ]
두 변수가 같은 대상을 바라보고 있기 때문에 나타나는 현상입니다.
엄격한 동등 연산자 ===
참고로 ==
라는 느슨한 동등 연산자도 있지만, 예상치 못한 결과를 낳을 수 있어 초보자라면 사용하지 않는 것을 강력히 추천합니다.
원시 값의 경우 ===
는 내용물이 같은지를 비교하거든요.
> 1 === 1
true
> 'hello' === 'hello'
true
하지만 객체의 경우 ===
는 내용이 아닌 ‘주소’가 같은지를 비교합니다.
그래서 내용물이 똑같아 보여도, 서로 다른 객체라면 false
를 반환하는데요.
이 점이 객체 비교에서 가장 헷갈리기 쉬운 부분입니다.
> [] === []
false
두 개의 빈 배열은 내용물은 같지만, 메모리상에서는 서로 다른 주소를 가진 별개의 객체이기 때문입니다.
그 외 비교 연산자 <, <=, >, >=
숫자를 비교할 때는 우리가 예상하는 대로 작동하지만, 문자열을 비교할 때는 사전 순서대로 비교합니다.
> '가방' < '바나나'
true
다만 대문자가 소문자보다 ‘크다’고 판단하는 등 몇 가지 주의할 점이 있습니다.
불리언을 위한 논리 연산자 &&, ||, !
&&
연산자는 양쪽 모두 true
일 때만 true
를 반환하고, ||
연산자는 둘 중 하나라도 true
이면 true
를 반환합니다.
!
연산자는 불리언 값을 반대로 뒤집는 역할을 하거든요.
> !true
false
> !false
true
이 연산자들을 활용하면 특정 값이 주어진 범위 안에 있는지 확인하는 함수도 쉽게 만들 수 있습니다.
const isBetween = (lower, upper, value) => {
return value >= lower && value <= upper;
};
이 함수는 value
가 lower
이상’이고’ upper
이하’일 때만 true
를 반환합니다.
if 조건문
if
문의 괄호 안에 있는 조건이 true
일 경우에만 중괄호 안의 코드가 실행됩니다.
if (조건) {
// 조건이 true일 때만 실행되는 코드
}
else
를 사용하면 조건이 false
일 때 실행될 코드를 추가할 수 있고, else if
를 사용하면 여러 개의 조건을 연달아 확인할 수도 있습니다.
const describeNumber = num => {
if (Number.isNaN(num)) {
return "숫자가 아닙니다";
} else if (Number.isInteger(num)) {
return "정수입니다";
} else {
return "실수입니다";
}
};
이 함수는 입력받은 num
이 숫자가 아닌지, 정수인지, 혹은 그 외의 실수인지를 순서대로 확인하여 해당하는 설명을 반환합니다.
프로젝트 숫자 맞추기 게임
게임이 시작되면 컴퓨터는 정해진 범위 내에서 무작위 숫자를 하나 생각합니다.
사용자는 숫자를 입력하고, 컴퓨터는 사용자의 추측이 정답보다 높은지, 낮은지, 아니면 정답인지를 알려주는 방식이거든요.
이 게임의 핵심 로직은 if-else if-else
구조로 이루어져 있습니다.
const continueGame = guessedNumber => {
// ... (입력값 유효성 검사) ...
if (guessedNumber === randomNumber) {
feedback.innerText = "✅ 정답입니다!";
// 게임 종료 처리
} else if (guessedNumber < randomNumber) {
feedback.innerText = "제가 생각한 숫자보다 작네요.";
} else {
feedback.innerText = "제가 생각한 숫자보다 크네요.";
}
};
먼저 사용자의 입력값이 유효한 숫자인지, 그리고 정해진 범위 내에 있는지 확인합니다.
유효한 추측이라면, if
문을 통해 정답과 비교하여 세 가지 경우에 따라 각기 다른 피드백을 화면에 보여주는 거죠.
사용자가 정답을 맞히면 게임이 종료되고, 더 이상 추측을 입력할 수 없도록 입력 필드와 버튼을 비활성화합니다.