본문 바로가기
프로그래밍/자바스크립트

JavaScript - 흐름 제어와 오류처리

by pentode 2022. 4. 4.

순차적으로 실행되는 명령을 조건에 따라 다른 명령을 실행할 수 있도록 해주는 흐름 제어(Flow Control)를 하는 방법을 알아봅니다.

 

1. 블록문

가장 기본적인 명령문은 세미콜론(;)으로 구분됩니다. 이러한 명령을 그룹으로 묶는 방법이 대괄호({}) 블록을 사용하는 것입니다. 블록은 함수, 조건문, 반복문, 에러처리 등에서 명령어 그룹을 묶는데 사용되어지며 변수의 유효범위를 결정하는 단위이기도 합니다.

 

{
    문장1;
    문장2;
    .
    .
    .
    문장n;
}


※참고
var를 사용하면 함수 레벨 유효범위가 되고, ES6에서 추가된 let, const를 사용하면 블록 레벨 유효범위가 적용됩니다.


2. 조건문

조건에 따라 프로그램 실행 흐름를 변경할 수 있는 기능을 제공하는 명령으로 if, switch가 있습니다.

 

2.1 if...else 문

if문을 사용하여 조건이 참 일때 명령을 실행할 수 있습니다. 선택적으로 거짓일때는 else를 사용하여 실행할 명령문을 제공할 수 있습니다.

 

// if문의 기본형태
if(조건) {
    문장1;
} else {
    문장2;
}

// 사용예
let x = 2;
let y = 3;
if(x > y) {
    conosle.log("x가 y보다 큽니다.");
} else {
    console.log("x가 y보다 작거나 같습니다.");
}

결과)
x가 y보다 작거나 같습니다.


위의 문장에서 조건이 참이면 문장1이 실행되고, 거짓이면 문장2가 실행됩니다.

else if를 사용해서 여러 조건은 검사할 수도 있습니다.

 

if(조건1) {
    문장1;
} else if(조건2) {
    문장2;
} else if(조건n) {
    문장n;
} else {
    마지막문장;
}


if문의 조건에는 true와 false로 평가되는 식 또는 값 외에도 어떠한 식이나 값도 올 수 있습니다. 다음은 거짓(false)으로 평가되는 값들입니다.

false : 원시 Boolean타입 false입니다.
undefined : 선언후 초기화 되지 않을때 갖는 값입니다.
null : 의도적으로 데이터가 없음을 나타내는 값입니다.
0 : 숫자 0 입니다.
NaN : 숫자가 아님을 나타내는 값입니다(주로 숫자가 아닌 문자열을 숫자로 변환하려고 할때 가지는 값입니다).
"" : 빈 문자열은 거짓입니다.

조건에 대입문(=)을 사용하면 참(true)로 평가됩니다. 오타를 주의해야 합니다.

 

let x = 1;
let y = 2;

if(x = y) {
    console.log("대입문을 항상 참으로 평가됩니다.");
}


if, else if, else 블록내에 실행할 문장이 하나밖에 없으면 블록 기호를 생략할 수 있습니다.

 

// 문장이 하나면 블록 기호 생략 가능
if(x < y)
    console.log("x가 y보다 작습니다.");
else
    console.log("x가 y보다 작거나 같습니다.");

 

2.2. switch 문

switch문은 표현식에 맞는 case문을 실행합니다. 맞는게 없으면 default문을 실행합니다.

 

//  기본형태
switch (표현식) {
    case 라벨1:
        문장1;
        break;
    case 라벨2:
        문장2;
        break;
    case 라벨n:
        문장n;
        break;
    default:
        기본문장;
}


사용예

 

let week = "월요일";
switch(week) {
    case "월요일":
        console.log("월요일 입니다.");
        break;
    case "화요일":
        console.log("화요일 입니다.");
        break;
    case "수요일":
        console.log("수요일 입니다.");
        break;
    case "목요일":
        console.log("목요일 입니다.");
        break;
    case "금요일":
        console.log("금요일 입니다.");
        break;
    case "토요일":
        console.log("토요일 입니다.");
        break;
    default:
        console.log("일요일 입니다.");
}


case에서 break; 문장을 빼먹으면 break를 만날때까지 아래 case를 실행하게 됩니다.


3. 예외 처리

나누기를 할때 나누는 값이 0이면 안되도록 확인해서 0이면 오류를 처리하는것을 예로 들어보겠습니다.

// 나누는 함수 입니다.
function divide(x, y) {
    return x / y;
}

// 변수를 선언합니다.
let x = 5;
let y = 0;
let z;

// 나누는 값이 0이면 오류처리를 하고, 아니면 결과를 출력합니다.
if(y !== 0) {
    z = x / y;
    console.log("결과 : " + z);
} else {
    console.log("0으로 나눌 수 없습니다.");
}


위의 예가 오류처리의 일반적인 방법이겠습니다. 프로그램을 하면 실제 작업 코드와 예외를 체크하는 코드가 복잡하기  섞여 나오게 됩니다.

위와 같은 방식에서 정상작업코드와 예외처리 부분을 분리해서 처리할 수 있게 해주는 문법이 제공됩니다. 여기서는 문제가 발생하면 예외를 던지고(throw), 예외가 발생할 수 있는 코드를 사용하는 쪽에서는 try, catch, finally 문을 사용해서 예외를 처리합니다.

 

// 나누는 함수 입니다.
function divide(x, y) {
    if(y === 0) {
        // 0으로 나누면 예외를 던집니다.
        throw "0으로 나눌 수 없습니다.";
    }
    return x / y;
}


// 예외를 던질수 있는 코드를 사용하는 쪽입니다.
let x = 5;
let y = 0;
let z;

try {
    // 나누기를 수행합니다.
    z = divide(x, y);
    
    // 결과를 출력합니다.
    console.log("result : " + z);
    
} catch (e) {

    console.error("catch : " + e);

} finally {
    console.log("finally : 항상 수행할 코드가 여기 옵니다.");
}

결과)
catch : 0으로 나눌 수 없습니다.
finally : 항상 수행할 코드가 여기 옵니다.


- 위의 예에서 divide함수는 0으로 나누게 되면 예외를 던집니다.
- divide함수를 호출하는 쪽에서는 try {} 블록 안에서 실행합니다.
- 예외가 발생하면 catch(e) {} 블록이 실행됩니다.
- finally {} 는 예외에 상관없이 항상 실행해야만 하는 코드가 있다면 사용합니다.

try {} 블록을 사용하면 반드시 catch 또는 finally중의 하나가 있어야 합니다.

예외가 발생했을때 throw 할 수 있는 값에는 제한이 없습니다. 원시형 데이터도 가능하고, 객체형 데이터도 가능합니다.

예외를 던질때 문자열외에 미리 정의되어 있는 Error 객체를 만들어서 던질 수 있습니다. 또한 Error 객체를 상속해서 사용자 예외 객체를 만들어서 던지는 것도 가능합니다.

Error객체에는 name, message속성이 있어서 각각 Error객체명과 에러 메세지를 가져올 수 있습니다.

 

// 나누는 함수 입니다.
function divide(x, y) {
    if(y === 0) {
        // Error 객체를 던집니다.
        throw new Error("0으로 나눌 수 없습니다.");
    }
    return x / y;
}


// 예외를 던질수 있는 코드를 사용하는 쪽입니다.
let x = 5;
let y = 0;
let z;

try {
    // 나누기를 수행합니다.
    z = divide(x, y);
    
    // 결과를 출력합니다.
    console.log("result : " + z);
    
} catch (e) {

    // 에러 내용을 출력합니다.
    console.error("catch : " + e);
    console.log("Error name : " + e.name);
    console.log("Error message : " + e.message);

} finally {
    console.log("finally : 항상 수행할 코드가 여기 옵니다.");
}

결과)
catch : Error: 0으로 나눌 수 없습니다.
(익명) @ test.html:32
Error name : Error
Error message : 0으로 나눌 수 없습니다.
finally : 항상 수행할 코드가 여기 옵니다.
반응형