프로그래밍에서 비교란 주어진 값들이 같은지, 다른지, 큰지, 작은지를 구분하는 것을 의미한다. 이때 비교 연산자를 사용하는데 비교 연산자의 결과는 true
나 false
중의 하나다. true
는 비교 결과가 참이라는 의미이고, false
는 거짓이라는 뜻이다.
==
는 동등연산자로 ""
과 0
, false
를 구분하지 못한다. ===
는 일치연산자(strict equality operator)로 형변환 없이 값을 비교한다.
자바스크립트엔 세 종류의 논리 연산자 ||
(OR), &&
(AND), !
(NOT)이 있다. 연산자에 '논리’라는 수식어가 붙긴 하지만 논리 연산자는 피연산자로 불린형뿐만 아니라 모든 타입의 값을 받을 수 있다. 연산 결과 역시 모든 타입이 될 수 있다.
false
값false
0
""
null
undefined
Nan
이외의 모든 것은 true
이다.
if
문조건에 따라 결과를 설정할 수 있다. if
문과 else
절로 조건을 걸고 그에 따른 코드를 실행한다. else
절은 if
조건에 거짓결과가 나올 때 실행된다.
let year = prompt('ECMAScript-2015 명세는 몇 년도에 출판되었을까요?', '');
if (year == 2015) {
alert( '정답입니다!' );
} else {
alert( '오답입니다!' ); // 2015 이외의 값을 입력한 경우
}
유사하지만 약간씩 차이가 있는 조건 여러 개를 처리해야 할 때가 있다. 이때 else if
로 복수조건을 처리할 수 있다.
let year = prompt('ECMAScript-2015 명세는 몇 년도에 출판되었을까요?', '');
if (year < 2015) {
alert( '숫자를 좀 더 올려보세요.' );
} else if (year > 2015) {
alert( '숫자를 좀 더 내려보세요.' );
} else {
alert( '정답입니다!' );
}
조건에 따라 다른 값을 변수에 할당해줘야 할 때가 있다.
let accessAllowed;
let age = prompt('나이를 입력해 주세요.', '');
if (age > 18) {
accessAllowed = true;
} else {
accessAllowed = false;
}
alert(accessAllowed);
'물음표(question mark) 연산자’라고도 불리는 '조건부(conditional) 연산자’를 사용하면 위 예시를 더 짧고 간결하게 변형할 수 있다.
조건부 연산자는 물음표?로 표시한다. 피연산자가 세 개이기 때문에 조건부 연산자를 '삼항(ternary) 연산자’라고 부르는 사람도 있다. 참고로, 자바스크립트에서 피연산자가 3개나 받는 연산자는 조건부 연산자가 유일하다.
let result = condition ? value1 : value2;
평가 대상인 condition
이 truthy라면 value1
이, 그렇지 않으면 value2
가 반환된다.
let accessAllowed = (age > 18) ? true : false;
age > 18
주위의 괄호는 생략 가능하다. 물음표 연산자는 우선순위가 낮으므로 비교 연산자 >
가 실행되고 난 뒤에 실행된다.
아래 예시는 위 예시와 동일하게 동작한다.
// 연산자 우선순위 규칙에 따라, 비교 연산 'age > 18'이 먼저 실행됩니다.
// (조건문을 괄호로 감쌀 필요가 없습니다.)
let accessAllowed = age > 18 ? true : false;
비교 연산자 자체가 true나 false를 반환하기 때문에 위 예시에서 물음표 연산자를 사용하지 않아도 된다.
// 동일하게 동작함
let accessAllowed = age > 18;
물음표 연산자?
를 여러 개 연결하면 복수의 조건을 처리할 수 있다.
let age = prompt('나이를 입력해주세요.', 18);
let message = (age < 3) ? '아기야 안녕?' :
(age < 18) ? '안녕!' :
(age < 100) ? '환영합니다!' :
'나이가 아주 많으시거나, 나이가 아닌 값을 입력 하셨군요!';
alert( message );
위 코드는 아래와 동일하게 동작한다.
if (age < 3) {
message = '아기야 안녕?';
} else if (age < 18) {
message = '안녕!';
} else if (age < 100) {
message = '환영합니다!';
} else {
message = '나이가 아닌 값을 입력 하셨군요!';
}
물음표 연산자?
는 조건에 따라 반환 값을 달리하려는 목적으로 만들어졌다. 이런 목적에 부합하는 곳에 물음표를 사용해야한다. 여러 분기를 만들어 처리할 때는 if
를 사용하자.
let company = prompt('자바스크립트는 어떤 회사가 만들었을까요?', '');
(company == 'Netscape') ?
alert('정답입니다!') : alert('오답입니다!');
if
사용let company = prompt('자바스크립트는 어떤 회사가 만들었을까요?', '');
if (company == 'Netscape') {
alert('정답입니다!');
} else {
alert('오답입니다!');
}
여러 동작을 반복해야 하는 경우 while
반복문 또는 for
반복문을 사용할 수 있다.
while (condition) {
// 코드
// '반복문 본문(body)'이라 불림
}
console.log("Print all odd numbers between 300 and 333");
var third = 300;
while(third <= 333) {
if(third % 2 == 1) { // third를 2로 나누었을때 나머지가 1
console.log(third);
}
third++; // third = third + 1
}
var answer = prompt("Are we there yet?");
while(answer.indexOf("yes") === -1) {
var answer = prompt("are we there yet?");
}
alert("yay!")
indexOf
: 부분 문자열의 있으면 위치를 알려준다. 없으면 -1
을 출력한다.let str = 'Widget with id';
alert( str.indexOf('Widget') ); // 0, str은 'Widget'으로 시작함
alert( str.indexOf('widget') ); // -1, indexOf는 대·소문자를 따지므로 원하는 문자열을 찾지 못함
alert( str.indexOf("id") ); // 1, "id"는 첫 번째 위치에서 발견됨 (Widget에서 id)
while(true)
를 써서 만든다. 무한 반복문은 여타 반복문과 마찬가지로 break
지시자를 사용해 멈출 수 있다.for (begin; condition; step) {
// ... 반복문 본문 ...
}
for (let i = 0; i < 3; i++) { // 0, 1, 2가 출력됩니다.
alert(i);
}
// For Loops
for(var count = 0; count < 6; count++) {
console.log(count);
}
// While Loops
var count = 1;
while(count < 6) {
console.log("count is: " + count);
count++
}
for
문의 구성 요소를 생략하는 것도 가능하다. 반복문이 시작될 때 아무것도 할 필요가 없으면 begin
을 생략하는 것이 가능하다.
let i = 0; // i를 선언하고 값도 할당하였습니다.
for (; i < 3; i++) { // 'begin'이 필요하지 않기 때문에 생략하였습니다.
alert( i ); // 0, 1, 2
}
step
역시 생략이 가능하다.
let i = 0;
for (; i < 3;) {
alert( i++ );
}
위와 같이 for
문을 구성하면 while (i < 3)
과 동일해진다. 모든 구성 요소를 생략할 수도 있는데, 이렇게 되면 무한 반복문이 만들어진다.
for (;;) {
// 끊임 없이 본문이 실행됩니다.
}
for
문의 구성요소를 생략할 때 주의할 점은 두 개의 ;
세미콜론을 꼭 넣어주어야 한다는 점이다. 하나라도 없으면 문법 에러가 발생한다.
대개는 반복문의 조건이 falsy가 되면 반복문이 종료된다. 그런데 특별한 지시자인 break
를 사용하면 언제든 원하는 때에 반복문을 빠져나올 수 있다.
아래 예시의 반복문은 사용자에게 일련의 숫자를 입력하도록 안내하고, 사용자가 아무런 값도 입력하지 않으면 반복문을 '종료’한다.
let sum = 0;
while (true) {
let value = +prompt("숫자를 입력하세요.", '');
if (!value) break; // (*)
sum += value;
}
alert( '합계: ' + sum );
(*)
로 표시한 줄에 있는 break
는 사용자가 아무것도 입력하지 않거나 Cancel버튼을 눌렀을 때 활성화된다. 이때 반복문이 즉시 중단되고 제어 흐름이 반복문 아래 첫 번째 줄로 이동한다.
반복문의 시작 지점이나 끝 지점에서 조건을 확인하는 것이 아니라 본문 가운데 혹은 본문 여러 곳에서 조건을 확인해야 하는 경우, '무한 반복문 + break’
조합을 사용하면 좋다.
continue
지시자는 break
의 '가벼운 버전’이다. continue
는 전체 반복문을 멈추지 않는다. 대신에 현재 실행 중인 이터레이션을 멈추고 반복문이 다음 이터레이션을 강제로 실행시키도록 한다(조건을 통과할 때). continue
는 현재 반복을 종료시키고 다음 반복으로 넘어가고 싶을 때 사용할 수 있다.
아래 반복문은 continue
를 사용해 홀수만 출력한다.
for (let i = 0; i < 10; i++) {
// 조건이 참이라면 남아있는 본문은 실행되지 않습니다.
if (i % 2 == 0) continue;
alert(i); // 1, 3, 5, 7, 9가 차례대로 출력됨
}
i
가 짝수이면 continue
가 본문 실행을 중단시키고 다음 이터레이션이 실행되게 한다(i
가 하나 증가하고, 다음 반복이 실행됨). 따라서 alert
함수는 인수가 홀수일 때만 호출된다.
여러 개의 중첩 반복문을 한 번에 빠져나와야 하는 경우가 종종 생깁니다.
i
와 j
를 반복하면서 프롬프트 창에 (0,0)
부터 (2,2)
까지를 구성하는 좌표 (i, j)
를 입력하게 해주는 예시를 살펴봅시다.
for (let i = 0; i < 3; i++) {
for (let j = 0; j < 3; j++) {
let input = prompt(`(${i},${j})의 값`, '');
// 여기서 멈춰서 아래쪽의 `완료!`가 출력되게 하려면 어떻게 해야 할까요?
}
}
alert('완료!');
사용자가 Cancel
버튼을 눌렀을 때 반복문을 중단시킬 방법이 필요합니다.
input
아래에 평범한 break
지시자를 사용하면 안쪽에 있는 반복문만 빠져나올 수 있습니다. 이것만으론 충분하지 않습니다(중첩 반복문을 포함한 반복문 두 개 모두를 빠져나와야 하기 때문이죠 – 옮긴이). 이럴 때 레이블을 사용할 수 있습니다.
레이블(label)
은 반복문 앞에 콜론과 함께 쓰이는 식별자입니다.
labelName: for (...) {
...
}
반복문 안에서 break <labelName>
문을 사용하면 레이블에 해당하는 반복문을 빠져나올 수 있습니다.
outer: for (let i = 0; i < 3; i++) {
for (let j = 0; j < 3; j++) {
let input = prompt(`(${i},${j})의 값`, '');
// 사용자가 아무것도 입력하지 않거나 Cancel 버튼을 누르면 두 반복문 모두를 빠져나옵니다.
if (!input) break outer; // (*)
// 입력받은 값을 가지고 무언가를 함
}
}
alert('완료!');
위 예시에서 break outer
는 outer
라는 레이블이 붙은 반복문을 찾고, 해당 반복문을 빠져나오게 해줍니다. 따라서 제어 흐름이 (*)
에서 alert('완료!')
로 바로 바뀝니다.
레이블을 별도의 줄에 써주는 것도 가능합니다.
outer:
for (let i = 0; i < 3; i++) { ... }
continue
지시자를 레이블과 함께 사용하는 것도 가능합니다. 두 가지를 같이 사용하면 레이블이 붙은 반복문의 다음 이터레이션이 실행됩니다.
아래 예시처럼 레이블을 사용하는 것은 불가능합니다.
break label; // 아래 for 문으로 점프할 수 없습니다.
label: for (...)
break
와 continue
는 반복문 안에서만 사용할 수 있고, 레이블은 반드시 break
이나 continue
지시자 위에 있어야 합니다.
// *** printReverse() ***
console.log("Connected");
function printReverse(arr){
for(var i = arr.length - 1; i >= 0; i--){
console.log(arr[i]);
}
}
printReverse([3,6,2,5])
// *** isUniform() ***
function isUniform(arr){
var first = arr[0];
for(var i = 0; i < arr.length, i++){
if(arr[i] !== first){
return false;
}
}
return true;
}
function isUniform(arr){
var first = arr[0];
arr.forEach(function(element){
if(element !== first){
return false;
}
});
return true;
}
// *** sumArray() ***
function sumArray(arr){
var total = 0;
arr.forEach(function(element){
total += element;
});
return total;
}
// *** max() ***
function max(arr){
var max = arr[0];
for(var i = 1; i < arr.length, i++){
if(arr[i] > max){
max = arr[i]
}
}
return max;
}