[0] flow control의 개요
1) flow control의 이해
컴퓨터의 기본 동작 : 개발자는 컴퓨터에게 명령하고, 컴퓨터는 수행
- 특정 trigger로 시작~종료되기까지의 흐름 존재
- 컴퓨터는 이 흐름을 상황별로 제어해야 함
Flow Control(제어 흐름, 흐름 제어)
: 명령형 프로그램의 개별 명령문, 명령 또는 함수 호출이 실행되거나 평가되는 순서
- 5가지 제어 흐름의 종류
- goto : 다른 구문에서 시작
- choice : 일부 조건이 충족되는 경우에만 일련의 명령문 실행
- loop : 어떤 조건이 충족될 때까지 일련의 명령문을 0회 이상 실행
- continue : 현재 실행 구문에서 떨어진 한 구문의 집합을 실행
- break : 프로그램 실행을 중단
Flow control의 종류
goto : 다른 구문에서 시작 <- 오류를 발생시킬수도 있음(권장x)
- choice : If-else, switch
- loop : Collection loop, General loop
- continue : Loop continuation
- break : Loop early exit, 함수 실행 정지
2) 표현식과 문의 개념
표현식 expression
: 어떤 값으로 이행되는 임의의 유효한 코드 단위
- 표현식이 평가되면, 새로운 값을 생성하거나 기존 값을 참조
- 값으로 평가될 수 있는 문은 모두 표현식
- 리터럴 표현식, 함수 표현식, ...
문 statement
: 프로그램을 구성하는 기본 단위, 최소 실행 단위 (== 명령문)
- 선언문, 할당문, 제어문, 반복문, 블럭문, ...
- 블럭문 (block statement)
- 명령문들을 그룹으로 묶을 수 있는 블럭문
- 한 쌍의 중괄호로 묶어서 표현
{
123;
const foo = 'apple';
function 함수() {
return 1;
}
}
- 제어문 (control flow statement)
| 제어문 | |
|---|
| choice | If...else, switch |
| Loop (iterations) | |
| - Loop early exit | break |
| - Loop continuation | continue |
| Subroutine exit | return |
| Non-local control flow | try...catch, throw, generator, async |
- 반복문 (iteration statement)
| 반복문 | |
|---|
| Conditional loop | while, do...while |
| General loop | for |
| Collection loop | for...in, for...of |
[1] choice - 조건문
조건문
: 일부 조건이 충족되는 경우에만 일련의 명령문 실행
1) if...else 문
- 논리조건의 참/거짓에 따라 명령문을 실행해야 할 경우 사용
- if문의 논리조건에는 true, false로 평가할 수 있는 표현식을 대입 가능
- 논리조건이 참인 경우, if 블럭문 실행. 거짓인 경우, else 블럭문을 실행
- 해당 값은 false로 평가(Falsy)
- false, undefined, null, 0, NaN, ""(empty string)
-> if...else문
- else if절을 사용하여, 다수의 조건을 순차적으로 검사할 수 있음

if...else문 - Nested Conditional
- 실제 로직을 구현할 때, 중첩 if문을 사용할 수도 있음
- 마틴 파울러의 리팩토링 자료
- nested conditional지양
- Guard Clauses 형태로 구현
2) switch 문
- switch에 명시된 표현식을 평가한 후, 평가된 값과 case 라벨 값을 비교하여 일치하는 case의 명령문을 실행
- default 작성 - 평가된 값에 해당하는 case문이 없을 경우, default의 명령문이 실행되도록
->switch문
- switch 표현식을 작성, 라벨이 포함된 case절을 작성
- default문은 라벨없이 작성
const foo = (parameter) => {
switch (parameter) {
case 1:
return 1;
case 2:
case 3:
return 23;
case 4:
return 4;
default:
return 0;
}
};
foo(3);
[2] Loop - 반복문
1) Conditional loop
조건부 loop
- 대부분의 프로그래밍 언어에는 일부 조건이 변경될 때까지 루프를 반복하는 구조가 있음
-> 시작할 때 조건을 평가하는 타입 - 본문 생략가능
- while문
while (표현식) {
...명령문...
}
-> 마지막에 조건을 평가하는 타입 - 본문은 한번 이상 실행
do {
...명령문...
} while(표현식);
ㅁ 조건부 loop - 주의사항※
- 종료될 수 있는 조건이 아닌경우, 무한 루프에 빠질 수 있음
- 조건문 작성시 주의

2) For loop
전통적인 for loop
- 특정 부분의 코드가 반복적으로 수행될 수 있도록 함
- 언어별로 지원하는 형식이 있음
(1) [초기화-조건식-증감문]의 형식
- C언어에서 유래한 문법
- while문과는 다르게, 해당 루프와 관련된 loop 변수 존재
- loop 변수의 비교 및 증감을 위한 별도 문법을 명시 필요
- ==loop 변수를 활용하여 명시적으로 카운트를 관리 필수
for([초기문]; [조건문]; [증감문]) {
...
}
- 초기문 : loop 내에서 사용할 loop변수를 초기화
- 조건문 : loop 내 코드 실행 전, 조건을 평가하여 loop를 지속할지 판단
- 증감문 : loop 내 코드 실행 후, 실행되는 문장 (루프변수 증감 용도)
(2) Collection loop (Foreach 루프)
- 컬렉션 안의 항목들을 횡단하는 제어흐름문
- For 문과 다르게, 명시적으로 카운터(루프변수)를 관리하지 않음
- 잠재적인 순환 횟수 오류를 예방 (off-by-one error)
- 자바스크립트 collection loop
- for...of문
- 반복 가능한 객체(iterator)를 통해 반복하는 루프를 만듦
for([변수] of [object]) {
...
}
-> 변수는 반복 가능한 객체의 값을 반환
-> 반복 가능한 객체 : Array, Set, String, ...
- for...in문
- 객체의 열거속성(enumerable)을 통해 지정된 변수를 반복
for([변수] in [object]) {
...
}
-> 변수는 객체의 key값을 반환
3) break문, continue문
break문
- 제어흐름의 종류 중 프로그램 실행 중단 종료
- 반복문, switch문을 종료시킬 때 사용
- 가장 가까운 while, do-while, for, switch문을 종료하고, 다음 명령어로 넘어감
const foo = () => {
for (let count = 0; count < 3; count++) {
console.log(count);
break;
}
};
foo();
continue문
- 제어흐름의 종류 중 현재 실행 구문에서 떨어진 한 구문의 집합을 실행 종류에 속함
- while, do...while, for문을 다시 시작하기 위해 사용
- 가장 안쪽의 while, do-while, for문을 둘러싼 반복을 종료하고, 다음 loop를 실행
- 전체 루프 실행을 종료하지 않음
- while : 조건문으로 이동
- for : 증감문으로 이동
const foo = () => {
for (let count = 0; count < 3; count++) {
console.log(count);
continue;
console.log('여기');
}
};
foo();
[3] 예외 처리하기
1) 예외 상황의 종류
예외 상황 Exception
- 런타임 때 발생할 수 있는 의도치 않은 상황을 뜻
- 흐름 제어 시 발생할 수 있는 예외 상황이므로, 이를 이해하여 코드 레벨에서 대응해야 함
- handling : 대응한다는 의미
- control : 예상하고 직접 조작한다는 의미
- 예외 상황을 핸들링하지 않는다면, 기능이 동작하지 않거나, 어플리케이션이 shout down될 수 있음
예외의 원인
: 언어 레벨 ~ 외부 요인에 의한 예외 상황까지 다양
- 코드 레벨에서의 문제
- 하드웨어, 디바이스의 문제
- 라이브러리 손상
- 사용자의 입력 실수
- ...
예외의 종류
2) throw와 Error 객체
throw문
: 예외를 발생시킬 때 사용
-> catch 블럭에서 에러 객체 핸들링
- 예외를 발생시키기 위해 throw문을 사용
- throw문 이후의 명령문은 실행되지 않음
const foo = () => {
console.log(1);
throw : 여기
console.log(2);
};
foo();
예외가 발생하면,
1. 현재 함수의 실행이 중지
2. 에러객체와 함께 에러가 throw
3. 제어흐름은
-> 호출자 사이에 catch블록이 있으면, catch블록으로 전달
-> 호출자 사이에 catch블록이 없으면, 프로그램 종료
Error객체
- 사용자가 직접 Error객체를 정의하여 사용할 수 있음
new Error('에러 메시지')
Error.message
Error.name
- ECMAScript 표준 내장 오류 유형이 있음
3) try...catch문
에러 catch
예외가 발생하면,
- 현재 함수의 실행이 중지
- 에러객체와 함께 에러가 throw
- 제어흐름은
-> 호출자 사이에 catch블록이 있으면, catch블록으로 전달
-> 호출자 사이에 catch블록이 없으면, 프로그램 종료
- 에러를 catch하여 프로그램이 종료되지 않도록 해야 함
- 예외 처리를 담당하는 핸들러를 찾기 위해, 순서대로 콜 스택(call stack)을 거슬러 올라가 올바른 핸들러를 찾아내 그 곳에서 처리되도록 함
콜 스택 call stack
- 스택 자료구조 : 출입구가 하나인 데이터 구조 (First In Last Out)
- Call stack
- 자바스크립트 코드가 실행되며 생성되는 실행 컨텍스트를 저장하는 자료구조
- 함수를 호출할 때마다 스택이 쌓이고, 함수의 실행이 종료되면 콜스택에서 스택을 제거하는 원리
- 에러 throw되면 콜 스택을 확인하여, 핸들링하고 있는 catch문이 있는 스택에서 처리
try...catch문
- 블록문 내에서 예외가 발생할 경우, 예외 처리를 맡을 하나 이상의 반응 명령문을 지정
- try 블록의 명령문 중 하나가 실패하면, catch로 제어권이 넘어감
- try 블록의 명령문 중 하나가 성공하면, catch로 제어권이 넘어가지 않음
- catch블럭에서 인자로 throw된 catchID를 참조할 수 있음
try {
...
}catch(catchID) {
...
}
-> 콜스택 중 하나에서 catch문에서 예외가 처리된다면, 더 상위의 콜 스택에서는 더 이상 예외가 타고 올라오지 않음
try...catch문의 finally블록
- finally블록은 try블록에서 예외 상황이 발생하지 않더라도, 실행됨
- 예외상황이 발생되면: try → catch → finally
- 예외상황이 발생되지 않으면: try → finally
const foo = (value) => {
if (value < 3) throw value;
else console.log(value);
};
const bar = (value) => {
try {
foo(value);
} catch (catchID) {
console.log('catch', catchID);
return catchID;
} finally {
console.log('finally');
}
};
bar(2);
try...catch문 - 사례
- 외부에서 의존되어 구현된 로직에서 사용 (예기치 못한 상황 대응)
- network 에러 발생 시
- 에러를 감지해야 하는 비지니스 로직
- 유저가 잘못된 데이터를 입력한 경우
- ...