이 글은 프로그래밍 경험이 없는 분들을 대상으로 자바스크립트 웹 앱 제작법을 알려드리는 ‘웹 개발 배우기’ 시리즈의 일부인데요.
이번 시간에는 특정 조건이 충족될 때만 코드 조각을 실행하기 위한 도구들에 대해 알아볼 건데요. 진리값(불리언), 비교, 그리고 if 문이 바로 그것입니다.
새로운 데이터 타입 불리언 (진리값) #
지금까지 우리는 숫자와 문자열이라는 두 가지 데이터 타입을 알고 있었는데요.
불리언은 다릅니다.
true와 false라는 단 두 개의 값만 존재하거든요.
이 값들은 함수나 메서드가 ‘예/아니오’ 질문에 답할 때 반환됩니다.
예를 들어, .startsWith() 메서드는 문자열이 특정 문자열로 시작하는지 알려줍니다.
> 'How are you?'.startsWith('How')
true
배열의 .includes() 메서드는 배열에 특정 요소가 포함되어 있는지 알려줍니다.
> ['a', 'b', 'c'].includes('x')
false
자바스크립트의 두 종류의 값 원시 값과 객체 #
더 배우기 전에, 약간의 이론을 탐구해야 하는데요. 이는 나중에 나올 내용을 이해하는 데 도움이 되기 때문입니다. 자바스크립트는 중요한 구분을 하거든요.
한쪽에는 undefined, 불리언, 숫자, 문자열과 같은 ‘원시 값(primitive values)‘이 있고요.
다른 한쪽에는 배열과 같은 ‘객체(objects)‘가 있습니다.
원시 값 #
원시 값은 ‘원자적’이고 ‘불변’하며 ‘값으로 비교’됩니다. 원시 값을 변수에 할당하면, 그 값은 해당 변수에 저장됩니다.
객체 #
객체는 ‘복합적’이고 ‘변경 가능’하며 ‘식별자로 비교’됩니다. 객체를 변수에 할당하면, 변수에는 객체 자체가 아닌 객체의 고유한 ‘식별자’(여권 번호처럼 생각하세요)가 저장되거든요. 실제 객체는 ‘힙(heap)‘이라는 별도의 메모리 공간에 저장됩니다.
할당은 객체를 공유합니다 #
왜 자바스크립트는 변수에 식별자를 저장할까요? 객체는 잠재적으로 매우 클 수 있기 때문인데요. 할당은 값을 복사하므로, 우리는 대량의 메모리를 복사하는 것을 피하고 싶습니다.
다음 할당은 배열 자체가 아닌, 배열의 식별자만 복사하는데요.
const arr1 = ['a', 'b', 'c'];
const arr2 = arr1;
흥미롭게도, arr1과 arr2는 이제 동일한 배열을 참조합니다.
그들은 그 배열을 ‘공유’하거든요.
따라서 arr1이 참조하는 배열을 변경하면, arr2가 참조하는 배열도 변경됩니다.
> arr1[1] = 'x';
> arr2
[ 'a', 'x', 'c' ]
[그림이 들어갈 위치]
할당은 원시 값을 복사합니다 #
숫자와 같은 원시 값의 경우, 우리는 변수 자체를 변경합니다.
> let num1 = 123;
> let num2 = num1;
> num1 = 0;
> num2
123
[그림이 들어갈 위치]
엄격한 동등 연산자 ===로 비교하기
#
엄격한 동등 연산자 ===는 피연산자가 같은지 아닌지를 알려주는데요.
원시 값 내용 비교하기 #
===의 피연산자가 원시 값이면, 그들의 내용을 보고 비교하는데요.
이를 ‘값으로 비교’라고 합니다.
> 1 === 1
true
> 'hello' === 'hello'
true
객체 식별자 비교하기 #
===의 피연산자가 객체이면, 그들의 식별자가 비교되는데요.
> [] === []
false
두 배열은 사람이 보기에는 같아 보이지만, 서로 다른 식별자를 가지고 있기 때문에 ===에게는 같지 않습니다.
이를 ‘식별자로 비교’라고 합니다.
<, <=, >, >=로 비교하기
#
자바스크립트에는 수학 연산자에 해당하는 연산자들도 있는데요. 숫자는 숫자적으로 비교되고, 문자열은 사전 순서와 유사하게 ‘사전적으로’ 비교됩니다.
불리언을 위한 두 연산자 논리 AND(&&)와 논리 OR(||)
#
논리 AND (&&)
#
자바스크립트의 논리 AND 연산자 &&는 인간의 언어 ‘그리고’와 똑같이 작동하는데요.
op1 && op2는 op1과 op2가 모두 true일 때만 true입니다.
논리 OR (||)
#
자바스크립트의 논리 OR 연산자 ||는 ‘그리고/또는’처럼 작동하는데요.
op1 || op2는 피연산자 중 하나 이상이 true이면 true입니다.
논리 NOT (!)
#
논리 NOT !은 불리언 값의 반대를 반환합니다.
!true는 false입니다.
if 문
#
하나 또는 두 개의 if 분기
#
if 문을 사용하면 불리언 값이 코드 조각의 실행 여부를 제어할 수 있는데요.
if (boolExpr) {
// `boolExpr`가 `true`일 때만 실행됨
} else {
// `boolExpr`가 `false`일 때만 실행됨
}
더 많은 if 분기
#
else if를 사용해 더 많은 분기를 추가할 수 있습니다.
const describeNumber = (num) => {
if (Number.isNaN(num)) {
return 'Not a number';
} else if (Number.isInteger(num)) {
return 'An integer';
} else {
return 'A floating point number';
}
};
프로젝트 describe-input.html
#
이 프로젝트는 이전 섹션의 describeNumber() 함수를 위한 사용자 인터페이스를 제공하는데요.
‘change’ 이벤트가 발생할 때마다, 이벤트 리스너는 입력을 가져와 describeNumber()에 전달하고, 그 결과를 ID가 ‘description’인 HTML 요소에 씁니다.
프로젝트 number-guessing-game.html
#
이 게임은 숫자를 “생각"하고 사용자가 어떤 숫자인지 추측해야 하는데요. 게임은 추측이 맞는지, 너무 높은지, 너무 낮은지를 알려주며 도움을 줍니다.
게임은 텍스트 필드를 통해 입력을 받고, 버튼을 통해 제출됩니다.
startGame() 함수는 추측할 숫자의 범위를 결정하는 LOWER와 UPPER 상수를 사용하고, getRandomIntegerBetween() 함수는 그 범위 내에서 무작위 정수를 생성합니다.
let randomNumber = undefined;
const startGame = () => {
randomNumber = getRandomIntegerBetween(LOWER, UPPER + 1);
// ...
};
사용자가 새로운 추측을 제출할 때마다 continueGame() 함수가 호출되는데요.
이 함수는 오류를 확인하고, 추측이 유효하면 사용자에게 피드백을 제공합니다.
만약 사용자가 정확히 맞혔다면, 게임은 끝나고 입력 버튼들이 비활성화됩니다.