[SW]/JavaScript (2025)

[자바스크립트] 섹션 11. 문제들에 대비하기

시원00 2025. 4. 13. 14:23
728x90

제대로 파는 자바스크립트(JavaScript) - by 얄코

(https://www.inflearn.com/course/제대로-파는-자바스크립트/dashboard)

섹션 11. 문제들에 대비하기

더보기
목차
11-1. 에러 핸들링
11-2. 구시대의 유물 var
11-3. 엄격 모드
11-4. 옵셔널 체이닝
11-5. 중간점검 퀴즈

11-1. 에러 핸들링

에러 핸들링 error handling의 필요성

에러 error 발생에 대비하지 않으면 프로그램이 종료됨

 

I. 자바스크립트의 에러 핸들링

1. try ... catch 문

try 블록: 에러 발생 여지가 있는 코드 포함. 이곳에서 발생한 에러는 프로그램을 멈추지 않음

catch 블록: 에러 발생 시 실행할 코드 포함. 발생한 오류 객체를 인자로 받음

 

2. try ... catch ... finally 문

finally 블록: 오류 발생 여부와 관계없이 한 번 실행되는 코드 포함

   try나 catch 문에 return이 있더라도 반드시 실행

 

II. Error 객체

에러 발생 시 던져지는 thrown 객체

에러에 대한 정보를 담고 있음

에러가 발생하지 않아도 직접 생성하여 던지기 가능

error도 객체임을 확인

 

1. 기본 생성과 사용법

 

기본 인스턴스 프로퍼티와 메서드

에러 자체를 로그 출력하면 나오는 문구

error.name도 수정 가능

 

의도적으로 에러 발생시키기

 

2. 에러의 여러 종류

Error로부터 상속받은 에러들: 어떤 문제에 의한 에러인지 쉽게 식별 가능하도록 함

주요 에러 설명
SyntaxError 문법에 이상이 있을 때
TypeError 주어진 명령에 적절한 자료형이 아닐 때
ReferenceError 잘못된 값을 참조했을 때
RangeError 유효한 범위를 벗어나는 숫자가 사용되었을 때

오류의 종류에 따라 대처하기

 

직접 오류를 생성하여 던지기

컴퓨터가 인지하지 못하는 에러 수동 발생

 

3. 커스텀 에러 만들기

 

(참고) 코드 해석하기

a. 에러나지 않을 때

b. 에러날 때

 

(참고) super(...)란?

super(...)는 부모 클래스의 생성자를 의미한다.

자바스크립트에서 클래스가 extends로 다른 클래스를 상속받을 때, 자식 클래스의 생성자(constructor) 안에서는 반드시 super(...)를 호출해야 한다. 즉, CustomError는 Error를 상속했기 때문에, Error 클래스의 생성자를 호출(super(...))해야 한다.

params : position을 제외한 나머지 인자들을 받아온 배열이다.

Super(...params) : Error 클래스는 생성자에서 에러 메시지를 받기 때문에, params에 담긴 인자들을 그대로 전달해서 Error 생성자를 초기화한다.

 

III. 에러 버블링 error bubbling

다른 함수를 호출했을 때, 에러 발생 시 해당 함수에서 잡지 않으면 호출한 곳으로 던져짐

다중 호출 시, 에러를 핸들링하는 코드가 있는 호출자까지 전달됨

에러는 가능한 발생한 곳 가까이서 처리하는 것이 좋음

 

func1 -> func2 -> func3 -> func4

try { throw e; } : 자신의 try 블록에서 발생한 예외로 간주되고, 그 아래에 있는 catch (e) 블록으로 바로 던져져서 처리된다.

catch (e) { throw e; } : 해당 함수의 바깥으로 예외가 전달된다.


11-2. 구시대의 유물 var

var: let과 const가 생기기 전 변수 선언에 사용되던 문

각종 문제점들을 갖고 있으므로 오늘날에는 사용하지 않을 것을 권장

 

1. 선언 없이도 사용 가능

 

2. 재선언 가능

코딩 중 실수의 여지가 됨

 

3. 블록 레벨 스코프 무시

 

함수의 스코프는 유효함

IIFE(Immideately Invoked Function Expression, 즉시 실행 함수)가 사용되었던 이유

 

4. 호이스팅

JavaScript 호이스팅은 인터프리터가 코드를 실행하기 전에 함수, 변수, 클래스 또는 임포트(import)의 선언문을 해당 범위의 맨 위로 끌어올리는 것처럼 보이는 현상을 뜻합니다.

var는 호이스팅되며, undefined로 초기화됨.

엄연히는 let도 호이스팅되지만, undefined로 초기화되지 않음. TDZ(Temporal Dead Zone, 초기화되기 이전의 영역)에 속함

 

var는 이 외에도 다양한 상황에서 예기치 못한 문제를 야기하기 때문에 사용하지 않는 것을 권장함


11-3. 엄격 모드

엄격 모드 strict mode

기존의 느슨한 모드에서 허용되던, 문제를 유발할 수 있는 코드들에 오류를 발생시킴

 

엄격 모드의 적용 방법 (범위별 적용 방법)

1. 문서 전체에 적용할 경우, 문서 최상단에 'use strict'; 작성 (큰 따옴표도 가능)

 

2. 문서, script 태그별로만 적용할 경우, 각각 작성

   (여러 .js 파일이 페이지에 사용될 시 각각 작성해야 함)

<!DOCTYPE html>
<html lang="ko">
<head>
    <script src="./1.js"></script>
    <script src="./2.js"></script>
</head>
</html>
// 1.js
'use strict'; // 엄격 모드 적용
x = 1;
console.log(x); // 오류 발생
// 2.js - 엄격 모드 적용하지 않음
y = 2;
console.log(y); // 오류 발생하지 않음

 

3. 해당 함수에만 적용할 경우, 함수의 최상단에 작성

 

엄격 모드의 효과

1. 선언되지 않은 변수 사용 시 오류 발생

엄격 모드 X
엄격 모드 O

 

2. 변수, 함수, 인자 등 삭제 불가한 것을 삭제 시 오류 발생

(참고) delete 연산자: 프로퍼티 삭제 (객체의 속성을 제거)

엄격 모드 X
엄격 모드 O

 

3. 인자명 중복 시 오류 발생

엄격 모드 X
엄격 모드 O

 

엄격 모드 사용 시 주의할 점

클래스나 모듈 등 ES6와 그 이후의 기능들 사용 시 엄격 모드가 기본으로 적용됨

엄격 모드가 모든 문제를 방지하는 수단이 되지는 않음

기존 코드에 엄격 모드 적용 시 예기치 못한 오류가 발생할 수 있음


11-4. 옵셔널 체이닝

유효하지 않을 수 있는 참조에 의한 문제들

네트워크 요청 등 어떤 값이 들어올지 모르는 상황에서 에러가 발생하는 상황들

1. undefined로부터 값에 접근할 때

2. null로부터 값에 접근할 때

3. 무효한 배열에 접근할 때

4. 존재하지 않는 함수를 호출할 때

 

다음과 같은 상황에서 에러를 피하기 위한 방법들

결과에 prop3이 있다면 가져와야 하는 상황

나올 수 있는 결과:

1. undefined prop3에 접근 시 TypeError

2. {} prop3에 접근 시 TypeError

3. {"prop1":{}} prop3에 접근 시 TypeError

4. {"prop1":{"prop2":{}}} prop3에 접근 시 undefined

5. {"prop1":{"prop2":{"prop3":"성공"}}} prop3에 접근 시 성공

 

 

에러를 피하기 위한 방법 1. if 문 활용

result, result.prop1, result.prop1.prop2까지 있을 경우만 result.prop1.prop2.prop3 출력

실행 결과:

 

에러를 피하기 위한 방법 2. && 활용

실행 결과:

 

에러를 피하기 위한 방법 3. try ... catch 문 활용

실행 결과:

 

?. 옵셔널 체이닝 optional chaining 연산자

호출 대상이 undefined나 null이어도 오류를 발생시키지 않음 (대신 undefined 반환)

존재 유무가 확실하지 않은 것으로부터 값을 읽거나 실행할 때 사용

 

(결과에 prop3이 있다면 가져와야 하는 상황에서)

에러를 피하기 위한 방법 4. 옵셔널 체이닝

실행 결과:

 

유무가 불확실한 함수를 호출할 때도 유용


11-5. 중간점검 퀴즈

1. NetworkError란 이름의 사용자 정의 Error 클래스를 만들어보세요.

기존의 Error를 확장하여, statusCode란 필드를 추가로 갖는 클래스입니다.

//  사용 예시

try {
  throw new NetworkError('네트워크 연결 오류', 404);
} catch (e) {
  console.log(e.name);
  console.log(e.message);
  console.log(e.statusCode);
}

예상 답:

class NetworkError extends Error {
    constructor (message, statusCode, ...params) {
        super(...params message);
        
        this.name = 'NetworkError';
        this.message = message;
        this.statusCode = statusCode;
    }
}

 

정답:

class NetworkError extends Error {
  constructor(message, statusCode) {
    super(message); 
    this.name = 'NetworkError';
    this.statusCode = statusCode;
  }
}

 

(참고) Error() 생성자

Error 생성자는 오류 객체를 생성합니다.
[매개변수] message (Optional) : 사람이 읽을 수 있는 오류 메시지입니다.

 

2. 아래와 같은 배열이 있습니다. 배열은 빈 배열일 수도 있고 아래와는 다른 내용의 값들이 들어 있을 수도 있습니다. 배열의 내용을 모르는 상태에서, 배열의 첫번째 객체가 name 프로퍼티를 갖고 있을 시 그 값을 모두 대문자로 출력하고 배열이 비었거나 첫 값의 형태가 다르다면 오류 없이 undefined 를 출력하는 코드를 작성해보세요.

const products = [
  { name: 'Phone', price: 700 },
  { name: 'Tablet', price: 900 }
];

//  배열의 내용이 아래와 같이 다를 수도 있음
//  []
//  [1, 2, 3]

예상 답:

console.log(products[0]?.name?.toUpperCase());

 

정답:

console.log( products[0]?.name?.toUpperCase() );

 

 

FIN.

728x90