혼공 자바스크립트 - Chapter 08

몽슈뜨·2022년 11월 8일
0
post-thumbnail

✨08-1 구문 오류와 예외

📌 오류의 종류

프로그래밍 언어의 오류에는 크게 2가지가 있습니다.

  • 프로그램 실행 전에 발생하는 오류
  • 프로그램 실행 중에 발생하는 오류

2가지 모두'오류'라고 부릅니다. 프로그램 실행 전에 발생하는 오류를 구문 오류 라고 부르며,
프로그램 실행 중에 발생하는 오류를 예외 또는 런타임 오류라고 구분하여 부릅니다.

  • 구문 오류
    구문 오류는 괄호의 짝을 맞추지 않았다든지, 문자열을 열었는데 닫지 않았다든지 할 때 발생하는
    오류입니다. 이러한 구문 오류가 있으면 웹 브라우저가 코드를 분석조차 하지 못하므로 실행 되지 않습니다.

    console.log("괄호를 닫지 않는 실수를 했습니다"
    
      구문 오류 : Uncaught SyntaxError: missing) after argument list

  • 예외
    예외 또는 런타임 오류는 실행 중에 발생하는 오류를 의미합니다.

     console.rog("log를 rog로 잘못 입력했습니다")
     
     	예외 오류 : Uncaught TypeError: console.rog is not a function

    이처럼 실행 중에 발생하는 오류가 예외입니다. 자바스트립에서는 SyntaxError 라고 출력되는
    오류 이외의 모든 오류(TypeError,ReferenceError,RangeError)가 예외로 분류됩니다.


    📌 기본 예외 처리

    조건문을 사용해서 예외가 발생하지 않게 만드는 것을 기본 예외 처리라고 부릅니다.
    다음 코드는 querySelector() 메소드로 문서 객체를 추출한 뒤 textContent속성에 글자를
    할당하는 코드입니다. 그런데 body 태그 내부에 h1 태그가 없습니다. 따라서 예외가 발생합니다.

    <!DOCTYPE html>
    <html>
     <head>
       <title></title>
     </head>
     <body>
     
     </body>
     <script>
       document.addEventListener('DOMContentLoaded', () => {
         const h1 = document.querySelector('h1')
         h1.textContent = '안녕하세요'
       })
     </script>
    </html>

    문서 객체를 선택했는데 문서 객체가 없는 경우라면, 다음과 같이 조건문으로 h1이 존재하는
    경우에만 teextContent속성을 변경하도록 예외 처리를 할 수 있습니다.

    <!DOCTYPE html>
    <html>
     <head>
       <title></title>
     </head>
     <body>
     
     </body>
     <script>
       document.addEventListener('DOMContentLoaded', () => {
         const h1 = document.querySelector('h1')
         if (h1) {
           h1.textContent = '안녕하세요'
         } else {
           console.log('h1 태그를 추출할 수 없습니다.')
         }
       })
     </script>
    </html>

    📌 고급 예외 처리

    이전 절에서 알아보았던 예외를 조금 더 쉽게 잡을 수 있는 기능으로 try catch finally 구문이
    있습니다. 이와 같은 try catch finally 구문을 사용해서 예외를 처리하는 방법을
    고급 예외 처리 라고 부릅니다.

    <!DOCTYPE html>
    <html>
     <head>
       <title></title>
       <script>
         try {
           willExcept.byeBye()
           console.log("try 구문의 마지막 줄")		// 위에서 예외가 발생하므로, 실행되지않고 catch 구문으로 이동
         } catch (exception) {
           console.log("catch 구문의 마지막 줄")
         }
       </script>
     </head>
     <body>
     </body>
    </html>
    

    "finally 구문은 무조건 실행된다." 라는 것을 생각하면서 다음 코드의 실행 결과를 예측해보세요.

    <!DOCTYPE html>
    <html>
     <head>
       <title></title>
       <script>
         try {
           willExcept.byeBye()
           console.log("try 구문의 마지막 줄")
         } catch (exception) {
           console.log("catch 구문의 마지막 줄")
         } finally {
           console.log("finally 구문의 마지막 줄")
         }
       </script>
     </head>
     <body>
     </body>
    </html>

    try 구문에서 예외가 발생하고 catch구문이 실행됩니다. try 구문에서 예외가 발생하든 안 하든
    무조건 finally 구문은 실행되므로 위와 같은 결과를 볼 수 있습니다.


  • finally 구문을 사용하는 이유
    try catch finally구문을 배우고나면 finally구문을 왜 써야 하는지 궁금증을 가질수 있다.
    catch구문 내부에서 finally 구문을 넣어도 결과가 비슷하게 나올 수 있다고 생각하기 때문입니다.

    두 코드의 실행 결과를 예측해 보세요. catch 구문 내부에서 return 키워드를 사용한 경우입니다.

    <!DOCTYPE html>			//예제 1번
    <html>
     <head>
       <title></title>
       <script>
         function test() {
           try {
             alert('A 위치입니다.')
             throw "예외 강제 발생"		// throw 키워드로 예외를 강제로 발생시킵니다.
           } catch (exception) {
             alert('B 위치입니다.')
             return
           }
           alert('C 위치입니다.')
         }
    
         // 함수를 호출합니다.
         test()
       </script>
     </head>
     <body>
     </body>
    </html>
    
    <!DOCTYPE html>			//예제 2번
    <html>
     <head>
       <title></title>
       <script>
         function test() {
           try {
             alert('A 위치입니다.')
             throw "예외 강제 발생"
           } catch (exception) {
             alert('B 위치입니다.')
             return
           } finally {
             alert('C 위치입니다.')
           }
         }
    
         // 함수를 호출합니다.
         test()
       </script>
     </head>
     <body>
     </body>
    </html>
    

    코드를 실행하면 예제1은 "A 위치입니다."와 "B 위치입니다." 만 출력합니다.
    return 키워드를 사용해 함수를 벗어났으므로 "C 위치입니다." 라는 글자를 출력하지 않는 것입니다.

    하지만 예제2는 "A 위치입니다.", "B 위치입니다.", "C 위치입니다."를 모두 출력합니다.
    이는 finally 구문을 반드시 실행한다는 특성 떄문입니다.

    • try catch 구문 내부에서 return 키워드를 만날때
    • try catch 구문 내부에서 break 또는 continue 키워드를 만날 때

✨08-2 예외 처리 고급

📌예외 객체

try catch 구문을 사용할 때 catch의 괄호 안에 입력하는 식별자가 예외 객체 입니다.
아무 식별자나 입력해도 괜찮지만, 일반적으로 eexception이라는 식별자를 사용합니다.

<!DOCTYPE html>
<html>
  <head>
    <title></title>
    <script>
      try {
        const array = new Array(999999999999999)
      } catch (exception) {
        console.log(exception)
        console.log()
        console.log(`예외 이름: ${exception.name}`)
        console.log(`예외 메시지: ${exception.message}`)
      }
    </script>
  </head>
  <body>
  </body>
</html>

<anonymous>2 : 파일이름
23 : 줄번호


📌 예외 강제 발생

상황에 따라서 예외를 강제로 발생시켜야 하는 경우도 있습니다. 예외를 강제로 발생시킬 때는
throw 키워드를 사용합니다.
throw 구문을 사용하면 곧바로 예외를 발생시킵니다.

<!DOCTYPE html>
<html>
  <head>
    <title></title>
    <script>
      function divide(a, b) {
        if (b === 0) {
          throw '0으로는 나눌 수 없습니다.'
        }
        return a / b
      }

      console.log(divide(10, 2))
      console.log(divide(10, 0))
    </script>
  </head>
  <body>
  </body>
</html>

예외를 강제로 발생시키는 이유는 무엇일까요? 일반적으로 개발할 때는 어떤 사람이 lodash라이브러리
처럼 다양한 기능을 가진 유틸리 함수( 또는 클래스 )를 만들고, 다른 사람들이 그러한 라이브러리의 함수를
활용하는 경우가 많습니다.

내가 만든 함수를 내가 사용할 때는 아무 문제 없이 사용할 수 있겠지만, 내가 만든 함수를 다른 사람이 사용할 때는 내가 의도하지 않은 형태로 코드를 사용할 수도 있습니다. 이럴 때 예외를 강제로 발생시키면
사용자에게 주의를 줄 수 있으며, 의도한 대로 처리하게 유도할 수 있습니다.

<!DOCTYPE html>
<html>
  <head>
    <title></title>
    <script>
      function test(object) {
        console.log(object.a + object.b)
      }

      test({})
    </script>
  </head>
  <body>
  </body>
</html>

일반적인 프로그래밍 언어라면,

  • object 객체에 a속성과 b속성이 없으므로 예외를 발생할 것이고,
  • 존재하지 않는 것을 더하므로 object.a + object.b를 할 때도 예외를 발생합니다.

그러면 사용자는 자신이 잘못 사용했다는 것을 인지하고 수정할 수있습니다.

하지만 자바스크립트는,

  • object.a가 undefined 나오며, object.b도 undefined로 나옵니다.
  • 여기서 undefined + undefined를 하면 NaN이 나옵니다.

즉 아무 오류 없이 코드가 정상적으로 실행됩니다.

이처럼 자바스트립트는 undefined와 NaN이라는 값이 있어서 다른 프로그래밍 언어에 비해서 예외를
많이 발생하지는 않습니다. 그렇기 때문에 사용자에게 함수를 잘못 사용했다는 것을 강제로라도
인지시켜줄 필요가 있다는 것입니다.

<!DOCTYPE html>
<html>
 <head>
   <title></title>
   <script>
     function test(object) {
       if (object.a !== undefined && object.b !== undefined) {
         console.log(object.a + object.b)
       } else {
         throw new Error("a 속성과 b 속성을 지정하지 않았습니다.")
       }
     }

     test({})
   </script>
 </head>
 <body>
 </body>
</html>

profile
개발자되면 맥북사줄께

0개의 댓글