제어문의 종류
- 블록문
- 조건문 : 조건에 따라 코드 불록을 실행할 때 사용
- 반복문 : 반복 실행할 때 사용
제어문 사용 이유
:일반적으로 위에서 아래로 흐르는 코드의 실행 흐름을 인위적으로 제어할 수 있다
제어문의 단점
: 코드의 실행 순서가 변경된다는 것은 단순히 위에서 아래로 순차적으로 진행하는 직관적인 코드의 흐름을 혼란스럽게 만든다
-> 코드의 흐름을 이해하기 어렵게 만들어 가독성을 해치고 오류를 발생시킬 수 있다
함수형 프로그래밍
: 제어문의 사용을 억제하여 복잡성을 해결하려고 한다
ex. forEach, map, filter, reduce 같은 고차 함수를 사용, 가독성 up
블록문 : 0개 이상의 문을 중괄호로 묶은 것
{
}
- 단독으로 사용
- 일반적으로 제어문 정의
- 함수를 정의할 때 사용
예제
//블록문
{var foo = 10; }
//제어문
var x=1;
if(x<10){x++;}
//함수 선언문
function sum(a,b){return a+b}
주어진 조건식(불리언 값으로 평가될 수 있는 표현식)의 평가 결과,
즉 논리적 참 또는 거짓에 따라 실행할 코드 블록을 결정한다
if(조건식1){
//조건식1이 참이면 실행
}else if (조건식2) {
//조건식2가 참이면 실행
}else{
//조건식1, 2가 모두 거짓이면 이 코드 블록 실행
}
cf. 만약 if문의 조건식이 불리언 값이 아닌 값으로 평가되면?
삼항 조건 연산자
: 조건문은 삼항 조건 연산자로 바꿀 수 있다
var x =2;
//0은 false로 취급
var result = x%2 ? '홀수' : '짝수';
console.log(result);//짝수
삼항 조건 연산자에서 경우의 수가 세가지라면?
var num=2;
//0은 false
var kind = num ? (num>0 ? '양수' : '음수'): '영';
console.log(kind)
삼항 조건 연산자 : 값으로 평가되는 표현식을 만든다
if...else문과 다르게 값처럼 사용할 수 있기 때문에 변수에 할당할 수 있다
정리
조건에 따라 단순히 값을 결정하여 변수에 할당하는 경우 : 삼항 조건 연산자
조건에 따라 실행해야 할 내용이 복잡해 여러 줄의 문이 필요한 경우 : if...else문
swtich문
: 주어진 표현식을 평가하여 그 값과 일치하는 표현식을 갖는 case문으로 실행 흐름을 옮긴다
case문
: 상황을 의미하는 표현식을 지정하고 콜론으로 마친다.
그리고 그 뒤에 실행할 문들을 위치시킨다
default문
: 일치하는 case문이 없다면 실행 순서는 default문으로 이동한다.
default문은 선택사항으로 사용할 수도 있고 사용하지 않을 수도 있다
switch(표현식){
case 표현식1:
switch 문의 표현식과 표현식1이 일치하면 실행될 문;
break;
case 표현식2:
switch 문의 표현식과 표현식2이 일치하면 실행될 문;
break;
default:
switch문의 표현식과 일치하는 case문이 없을 때 실행될 문;
여기는 break를 사용하지 않아도 실행이 종료되니까 필요 없다
}
if...else문 vs swtich문
case문에 break를 사용하지 않을 경우
: switch문의 표현식의 평가 결과와 일치하는 case문으로 실행 흐름이 이동하여 문을 실행 후, fall through가 일어났기 때문
fall through란?
: switch문을 탈출하지 않고 이후 모든 case문과 default문을 실행하는 것
var month = 1;
var monthName;
switch(month){
case 1: monthName = 'January'
case 2: monthName = 'February'
default: monthName = 'Invalid month'
}
console.log(monthName);//'Invalid month'
위와 같이 되는 이유
: case 1과 일치해서 monthName에 January가 할당되지만 break가 없어서
아래 February도 재할당되고 default까지 Invalid month가 또 재할당된다
swtich문
- 일치하는 값을 찾는다
- break가 있으면 거기서 switch문이 끝난다
- break가 없으면 일치하지 않더라도 아래 case들을 다 돌고 default까지 돌면서 재할당된다
- 일치하는 값이 없으면 default문에서 재할당된다
cf. break : 코드 블록에서 탈출하는 역할
break문이 없다면 case문의 표현식과 일치하지 않더라도 실행 흐름이 다음 case문으로 연이어 이동한다
여러 case를 한 번에 사용하기
//윤년 계산 알고리즘
1. 연도가 4로 나누어 떨어지는 해
2. 4로 나누어 떨어지더라도 100으로 나누어 떨어지면 안된다
3. 400으로 나눠떨어지면 윤년
var year = 2000;
var month=2;
var days=0;
switch(month){
case1: case3: case5: case7: case8: case 10: case12:
days = 31;
break;
case4: case6: case9: case11:
days=30;
break;
case 2:
//
days = ((year%4 ===0 && year%100 !==0) || (year%400===0)) ? 29 : 28;
break;
default:
console.log('Invalid month');
}
console.log(days);
}
정리
if...else문을 사용하는 편이 좋다. 조건문이 너무 많은 경우에먼 가독성을 위해 switch사용
for문
while문
do...while문
반복문 대신 사용할 수 있는 것들
forEach 메서드 : 배열 순회 시 사용
for...in문 : 객체의 프로퍼티 열거 시 사용
for...of문 : ES6에서 도입된 이터러블 순회할 때 사용 ex. 배열
조건식이 거짓으로 평가될 때까지 코드 블록을 반복 실행한다
for(변수 선언문 또는 할당문; 조건식; 증감식){
조건식이 참인 경우 반복 실행될 문;
}
for(var i=0; i<2; i++){
console.log(i)
}
실행 순서
- 변수 선언문 var i=0 실행 (단 한번만 실행된다)
- 변수 선언문의 실행이 종료되면 조건식 실행
- 조건식 평가 결과가 true면 코드 블록 실행
- 코드 블록 실행 종료 시 증감식 i++
- 증감식 실행 종료 시 다시 조건식 실행
3~5번 반복
n. 조건식 실행 시 false면 for문의 실행 종료
for(;;){...}
주어진 조건식의 평가 결과가 참이면 코드 블록을 계속해서 반복 실행
for문 vs while문
- for : 반복 횟수가 명확할 때 사용
- while : 반복 횟수가 불명확할 때 사용
var count=0;
while(true){
console.log(count)
count++;
if(count ===3)break;
}
코드 블록을 먼저 실행하고 조건식을 평가한다
-> 코드블록 무조건 한 번 이상 실행
var count=0;
do{
console.log(count);
count++;
}while(count<3)
cf. 레이블문 : 식별자가 붙은 문. 프로그램의 실행 순서를 제어하는 데 사용한다
switch문의 case문과 default문도 레이블 문
ex.
foo:{
console.log(1);
break foo; //foo레이블 블록문을 탈출한다
console.log(2);
}
var string='Hello World';
var search='l'
var index;
for(var i=0; i<string.length; i++){
if(string[i]===search){
index=i; //찾았으면 반복문 탈출
break;
}
}
console.log(index);
outer: for(var i=0; i<3; i++){
for(var j=0; j<3; j++){
if(i+j === 3)break outer;
console.log(`inner [${i}, ${j}]`);
}
}
console.log('Done!');
레이블 문은 중첩된 for문 외부로 탈출할 때 유용하지만 그 밖의 경우에는 일반적으로 권장하지 않는다. 레이블 문을 사용하면 프로그램의 프름이 복잡해져서 가독성이 나빠지고 오류를 발생시킬 가능성이 높아지기 때문이다.
let str = 'hello world'
var search = 'l'
var count=0;
for(var i=0; i<string.length; i++){
if(string[i] !== search) continue; //현 시점에서 실행 중단, 반복문의 증감식으로 이동
count++; //continue가 실행되면 이 문은 실행되지 않는다
}
console.log(count);
//continue문을 사용하지 않으면 if문 내에서 코드를 작성해야 한다
for(var i=0; i<string.length; i++){
if(string[i] !== search) {
count++; //continue가 실행되면 이 문은 실행되지 않는다
}
}
console.log(count);