
프로그래밍에서 여러 반복을 거쳐야 하는 과정의 경우가 생긴다면 반복문을 사용하여 줄일 수 있다.
변수가 증감, 증가하며 조건에 부합하거나 부합하지 않으면 반복문을 탈출하는 식이 대부분이다.
조건을 잘 걸어서 무한루프(loop)에 빠지지 않도록 하자 반복문의 종류는 아래에서 이어가겠다.
while 반복문의 문법은 우선 아래와 같다.
let i = 0;
while( i < 3 ){//()안에 조건을 둔다. 해당 조건이 참이라면 반복을 진행한다.
alert(i); //결과적으로 0, 1, 2가 출력된다.
i++;; //조건에 들어가는 변수를 증감 또는 증가하여 반복문을 탈출할 때까지 반복한다.
//조건에 들어가는 i의 변화가 없었더라면 무한루프가 됐을 것이다.
}
조건문의 참과 거짓 값에는 앞에서 배웠던 불린형이 쓰인다 예를 들자면
let i = 3;
while (i) { // i가 0이 되면 조건이 falsy가 되므로 반복문이 멈춥니다.
alert( i );
i--;
}
이처럼 false 값을 가지는 0 또는 null, defined도 반복문을 멈추게 한다.
앞선 while문은 조건을 따지고 반복문을 돈다.
반면 이번 do...while문은 우선 반복문을 진입하고 마지막에 조건을 따지는 방식이다.
예는 아래와 같다.
let i = 0;
do {
alert( i );//0, 1, 2이 출력된다.
i++;
} while (i < 3);
이처럼 조건이 아래에 위치하여 반복문 안의 내용을 최소한 한 번이라도 실행해야 할 때 사용한다.
대다수의 상황에서는 do...while보다 while문이 적합하다고 한다.
for 반복문은 앞서 나온 반복문들 보다는 복잡하지만 가장 많이 쓰이는 반복문이다.
기본 구성은 아래와 같고
for (begin; condition; step) {
// ... 반복문 본문 ...
}
컴퓨터에서 읽혀지는 순서는
condition이 true -> 반복문 본문 실행 -> step 실행 이고
condition이 false -> 반복문 본문 진행하지 않음 -> 반복문 탈출
이것이 기본적인 for 반복문의 알고리즘이다.
예는 아래와 같다.
for (let i = 0; i < 3; i++) { // 0, 1, 2가 출력된다.
alert(i);
}
이 코드에서는 안에서 이러한 식으로 읽힌다.
let i = 0
→ (i<3은? -> true (0<3) → alert(i);실행 ( 0 ) -> i++ (i==1)이 된다.)
→ (i<3은? -> true (1<3) → alert(i);실행 ( 1 )-> i++ (i==2)이 된다.)
→ (i<3은? -> true (2<3) → alert(i);실행 ( 2 )-> i++ (i==3)이 된다.)
→ (i<3은? -> false (3<3) → 반복문 탈출)
지금까진 카운터 변수 i를 반복문 안에서 선언하였다. 이런 방식을 인라인 변수 선언이라고 부른다.
이렇게 선언한 변수는 반복문 안에서만 접근할 수 있다.
for (let i = 0; i < 3; i++) {
alert(i); // 0, 1, 2
}
alert(i); // Error: i is not defined
인라인 변수 선언 대신, 정의되어있는 변수를 사용할 수도 있다.
let i = 0;
for (i = 0; i < 3; i++) { // 기존에 정의된 변수 사용
alert(i); // 0, 1, 2
}
alert(i); // 3, 반복문 밖에서 선언한 변수이므로 사용할 수 있음
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++ );//i 를 출력하고 ++
//alert(i);
//i++; 와 동일하다.
}
사실 모든 구성 요소를 생략할 수도 있는데 이렇게 되면 무한 반복문이 만들어진다.
for (;;) {
// 끊임 없이 본문이 실행됩니다.
}
for문의 구성요소를 생략할 때 주의할 점은 두 개의 ; 세미콜론을 꼭 넣어주어야 한다는 점이다.
하나라도 없으면 문법 에러가 발생합니다.
또한 이런 무한루프가 발생할 때 반복문을 빠져나오는 법이 있다.
그것은 바로 다음에 이어진다.
대개는 반복문의 조건이 false가 되면 반복문이 종료된다.
그런데 특별한 지시자인 break를 사용하면 언제든 원하는 때에 반복문을 빠져나올 수 있다.
아래 예시의 반복문은 입력되는 숫자들을 모두 더해주는데
사용자가 아무런 값도 입력하지 않으면 반복문을 '종료’하도록 돼있다.
let sum = 0;
while (true) {
let value = +prompt("숫자를 입력하세요.", '');
if (!value) break; // 아무것도 입력하지 않았거나
//취소 버튼을 눌렀을 때 활성화 되는 부분.
sum += value;//값이 입력됐다면 sum에 누적함
}
alert( '합계: ' + sum );
continue 지시자는 전체 반복문을 멈추지 않아서 break의 '가벼운 버전’이다.
현재 실행 중인 반복을 멈추고 반복문에서 다음 다음 반복으로 강제 실행시키도록 한다 (조건을 통과할 때).
이처럼 continue는 현재 반복을 종료시키고 다음 반복으로 넘어가고 싶을 때 사용할 수 있다.
아래 반복문은 continue를 사용해 홀수만 출력합니다.
for (let i = 0; i < 10; i++) {
// 조건이 참이라면 남아있는 본문은 실행되지 않습니다.
if (i % 2 == 0) continue;//짝수라면 다음 반복으로 넘어감
alert(i); //따라서 홀수인 1, 3, 5, 7, 9가 차례대로 출력됨
}
홀수를 출력해주는 예시는 아래처럼 생길 수도 있다.
for (let i = 0; i < 10; i++) {
if (i % 2) {//나머지가 1(true)이라면 출력
alert( i );//따라서 나머지가 남는 홀수들만 출력
}
}
표현식이 아닌 문법 구조(syntax construct)는 삼항 연산자 ?에 사용할 수 없다는 점을 항상 유의하시기 바랍니다. 특히 break나 continue 같은 지시자는 삼항 연산자에 사용하면 안 된다.
if (i > 5) {
alert(i);
} else {
continue;
}
물음표를 사용해서 위 조건문을 아래와 같이 바꾸려는 시도를 할 수 있을 것이다.
(i > 5) ? alert(i) : continue; // 여기에 continue를 사용하면 안 됩니다.
이런 코드는 문법 에러를 발생시킨다.
이는 물음표 연산자 ?를 if문 대용으로 쓰지 말아야 하는 이유 중 하나다.
continue사용 시에는 if문을 사용하도록 하자.
여러 개의 중첩 반복문을 한 번에 빠져나와야 하는 경우가 종종 생기곤 한다.
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})의 값`, '');
//begin이 j인 반복문 내에서 행동이 이루어 지는데 여기서 사용자의 입력이 없거나 취소 버튼을 누른 경우
//탈출을 하여도 begin이 i인 반복문이 진행된다.
// 여기서 멈췄을 때 두 개의 반복문을 끝내며 아래쪽의 `완료!`가 출력되게 하려면 어떻게 해야 할까?
}
}
alert('완료!');
이럴 때 사용되는 것이 레이블이다.
반복문에 레이블로 식별자를 달아주어 break나 continue 시에 해당 반복문을 빠져나오거나 다음 반복으로 넘어갈 수 있게 한다.
레이블을 사용하는 법은 아래와 같다.
labelName: for (...) {
...
}
아까 반복문에 대입을 해본다면
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('완료!');
이처럼 큰 반복문에 'outer'라는 식별자를 달아 값을 받지 못했을 시에 식별자를 달은 반복문을 종료시키는 모습이다.
레이블 식별자를 선언하고 다음 줄에 쓰는 것도 인식을 하며
레이블 식별자 선언 후에 해당 반복문 안에 해당 식별자를 이용한 break, continue는 안에 위치하여야 한다.
switch문은 일치하는 값을 찾아 실행하는 구조이다.
복수의 if 조건문은 switch문으로 바꿀 수 있다.
switch문을 사용한 비교법은 특정 변수를 다양한 상황에서 비교할 수 있게 해준다.
코드 자체가 비교 상황을 잘 설명한다는 장점도 있다.
문법은 아래와 같은 형식이다.
switch문의 내부 구조는 하나 이상의 case문으로 구성된다.
대개 default문도 있지만 이는 필수는 아니다.
switch(x) {
case 'value1': // if (x === 'value1')
...
[break]
case 'value2': // if (x === 'value2')
...
[break]
default:
...
[break]
}
이전 반복문들 처럼 전체 반복은 아니고 case 1부터 시작하여 마지막 case 혹은 default 까지 한 번만 진행한다.
그리고 case 내부 구문에 break가 있거나 switch문은 탈출하게 된다.
다만 case 조건이 맞다면 해당 case 내부의 구문을 실행하고 다음으로 넘어간다.
아래는 switch문의 예시이다.
let a = 2 + 2;
switch (a) {//a 변수를 받아 case에 적힌 수와 비교한다.
case 3://a가 3이라면
alert( '비교하려는 값보다 작습니다.' );
case 4://a가 4이라면 = a가 4이기에 해당 구문이 실행되고 다음 case로 넘어간다.
alert( '비교하려는 값과 일치합니다.' );
case 5://a가 5이라면
alert( '비교하려는 값보다 큽니다.' );
default://a의 값이 입력되지 않았거나 정의되지 않았을 때.
alert( "어떤 값인지 파악이 되지 않습니다." );
}
이 코드에서 문제점은 수를 비교하지만 case와 default 내부에 break가 있지 않아서 비교하더라도 상관없는 다음 case의 구문까지 출력된다.
때문에 각 case 내부에 break를 넣어주는 것이 맞다.
switch문과 case문은 모든 형태의 표현식을 인수로 받는다.
let a = "1";
let b = 0;
switch (+a) {
case b + 1:
alert("표현식 +a는 1, 표현식 b+1는 1이므로 이 코드가 실행됩니다.");
break;
default:
alert("이 코드는 실행되지 않습니다.");
}
표현식 +a를 평가하면 1이 됩니다. 이 값은 첫 번째 case문의 표현식 b + 1을 평가한 값(1)과 일치하죠. 따라서 첫 번째 case문 아래의 코드가 실행됩니다.
코드가 같은 case문은 한군데 묶을 수 있다.
let a = 3;
switch (a) {
case 4:
alert('계산이 맞습니다!');
break;
case 3: // (*) 두 case문을 묶음
case 5:
alert('계산이 틀립니다!');
alert("수학 수업을 다시 들어보는걸 권유 드립니다.");
break;
default:
alert('계산 결과가 이상하네요.');
}
case 3과 case 5는묵었기에 case 3과 case 5는 동일한 메시지를 보여준다.
switch/case문에서 break문이 없는 경우엔 조건에 상관없이 다음 case문이 실행되는 부작용이 발생한다. 위 예시에서 case 3이 참인 경우엔 (*)로 표시한 줄 아래의 코드가 실행되는데, 그 아래 줄엔 case 5가 있고 break문도 없기 때문에 12번째 줄의 break문을 만날 때까지 코드는 계속 실행된다.
출처
내용 : https://ko.javascript.info/intro
썸네일 제작 : https://www.canva.com/