조건에 따라 코드 블록을 실행하거나 반복 실행 할 때 사용한다. 제어문을 사용하면 코드의 실행 흐름을 인위적으로 제어할 수 있다.
0개 이상의 문을 중괄호로 묶은 것, 하나의 실행 단위로 취급됨. 블록문은 주로 제어문이나 함수를 정의할 때 사용된다. 블록문은 언제나 문의 종료를 의미하는 자체 종결성을 갖어 세미콜론을 붙이지 않는다.
주어진 조건식의 평과 결과에 따라 코드 블록의 실행을 결정한다. 조건식
은 불리언 값으로 평가될 수 있는 표현식
이다. if 문의 조건식은 불리언 값
으로 평가 되어야 한다. 만약 아니라면 자바스크립트 엔진은 암묵적으로 불리언 값으로 타입 변환한다.
조건식의 평가 결과가 참인 경우 코드 블록을 실행한다. 그 후 조건식을 다시 평가하여 여전히 참인 경우 코드 블록을 다시 실행한다. 조건식이 거짓일 때까지 반복한다.
for(var i = 1; i <=6; i++)
{
for(var j = 1; j <=6; j++)
{
if(i + j === 6) console.log(i, j);
}
}
// 1 5
// 2 4
// 3 3
// 4 2
// 5 1
//이미 조건식의 평가는 false임에도 코드 블록은 실행 된다.
var count = 0;
do {
console.log(count);
count++;
console.log(count);
}while (count < 0);
console.log(`Ended with ${count}`);
// 0
// 1
// Ended with 1
var count = 0;
do {
console.log(count);
count++;
console.log(count);
}while (count < 3);
console.log(`Ended with ${count}`);
// 0
// 1
// 1
// 2
// 2
// 3
// Ended with 3
브레이크 문은 반복문을 더 이상 진행하지 않아도 될 때 불필요한 반복을 회피할 수 있어 유용함.
break 문의 위치에 따른 (여부에) 따른 결과값 변화 예시를 보자.
var string = 'Bumi Kim';
var search = 'I';
var index;
string = string.toUpperCase()
search = search.toUpperCase()
// if 문 블록 안에 break 를 걸었을 때는 예상했던 동작대로
search의 첫번째 탐색 값을 반환해주었다.
for (var i = 0; i < string.length; i++)
{
if(string[i] === search){
index = i;
break;
}
}
console.log(`'${search}' is on ${index}th of ${string}`)
//'I' is on 3th of BUMI KIM
// break문을 빼거나 if 문에서 꺼냈을 때는
for문을 전부 돌고 해당하는 마지막 i 값을 반환했다.
여기서 브레이크는 사실상 아무런 영향을 미치지 않는다.
for (var i = 0; i < string.length; i++)
{
if(string[i] === search)index = i;
break;
}
console.log(`'${search}' is on ${index}th of ${string}`)
//'I' is on 6th of BUMI KIM
레이블 문, 반복문, 스위치문의 코드 블록을 탈출한다. 이외의 문에 break 문을 사용하면 syntaxError occurs.
if(true) {
break;
}
//Uncaught SyntaxError: Illegal break statement
foo: {
console.log(1);
break foo;
console.log(2);
}
console.log('done');
// 1
// done
레이블문이 아닌 코드블록에 사용하면 에러 뜸
{
console.log(1);
break;
console.log(2);
}
console.log('done');
//Uncaught SyntaxError: Illegal break statement
중첩된 for문의 내부 for 문에서 break 문을 실행하면 내부 for문을 탈출하여 외부 for문으로 진입한다. 이때 내부 for문이 아닌 외부 for문을 탈출하려면 레이블 문을 사용한다.
//레이블 문을 사용했다.
외부 for문까지 탈출하여 i + j === 6인 첫번째 경우를 부합하자마자 반복문 자체를 종결.
outer: for(var i = 1; i <=6; i++)
{
for(var j = 1; j <=6; j++)
{
if(i + j === 6) break outer;
console.log(`inner ${i}, ${j}`);
}
}
VM807:6 inner 1, 1
VM807:6 inner 1, 2
VM807:6 inner 1, 3
VM807:6 inner 1, 4
레이블 문을 사용하지 않았을 때와 다른 동작을 볼 수 있다. i + j === 6인 경우를 부합 했을 때 내부 for 문을 탈출하여 외부 for문으로 재진입한다.
for(var i = 1; i <=6; i++)
{
for(var j = 1; j <=6; j++)
{
if(i + j === 6) break;
console.log(`inner ${i}, ${j}`);
}
}
VM832:6 inner 1, 1
VM832:6 inner 1, 2
VM832:6 inner 1, 3
VM832:6 inner 1, 4
VM832:6 inner 2, 1
VM832:6 inner 2, 2
VM832:6 inner 2, 3
VM832:6 inner 3, 1
VM832:6 inner 3, 2
VM832:6 inner 4, 1
VM832:6 inner 6, 1
VM832:6 inner 6, 2
VM832:6 inner 6, 3
VM832:6 inner 6, 4
VM832:6 inner 6, 5
VM832:6 inner 6, 6
문자열에서 특정 문자의 개수를 세는 예시이다.
여기서 바보같은 실수를 했는데 오히려 좋다.
count를 0으로 재할당 하지 않고 undefined 상태로 진행한 코드와, 0으로 재할당 하여 진행 한 코드의 결과 값이 달랐다. 언제부터 내 이름에 I가 세개 있었던건지 진지하게 고민했다.
var string = 'bumi Kim'.toUpperCase();
var search = 'i'.toUpperCase();
var count;
for(var i = 0; i < string.length; i++)
{
if(search === string[i]) count++;
}
console.log(`${string} has ${count} of ${search}`);
VM2432:9 BUMI KIM has 3 of I // ????? 눈을 의심
//undefined 값이 자동으로 +1 할당을 하는건가 뭔가 고민해보다가
크롬 개발자 도구에서 이전에 지워지지 않은 값으로 사용된것으로 판명.
var string = 'bumi Kim'.toUpperCase();
var search = 'i'.toUpperCase();
var count;
for(var i = 0; i < string.length; i++)
{
if(search === string[i]) count++;
}
console.log(`${string} has ${count} of ${search}`);
VM545:9 BUMI KIM has NaN of I
count = 0;
0
for(var i = 0; i < string.length; i++)
{
if(search === string[i]) count++;
}
console.log(`${string} has ${count} of ${search}`);
VM2464:6 BUMI KIM has 2 of I
명심하자 undefined + 숫자는 NaN을 뱉는다는것
var value;
undefined
console.log(value + 1);
VM755:1 NaN