Study/모던 자바스크립트 Deep Dive

[모던 자바스크립트 Deep Dive] 46장 ~ 49장

chaeon1 2025. 5. 11. 01:08

46장 제너레이터와 async/await

46.1 제너레이터란?

  1. 제너레이터 함수는 함수 호출자에게 함수 실행의 제어권을 양도할 수 있다.
  2. 제너레이터 함수는 함수 호출자와 함수의 상태를 주고받을 수 있다.
  3. 제너레이터 함수를 호출하면 제너레이터 객체를 반환한다.

46.2 제너레이터 함수의 정의

  • function* 키워드로 선언, yield 표현식 포함
  • 선언문, 표현식, 메서드, 클래스 메서드 형태
  • 화살표 함수로 정의 불가
  • new 생성자로 호출 불가

46.3 제너레이터 객체

  • 일반 함수: 호출 시 코드 블록 실행
  • 제너레이터 함수: 호출 시 제너레이터 객체 생성 후 반환
  • 제너레이터 객체는 이터러블이면서 동시에 이터레이터
    • Symbol.iterator
    • next: 호출 시 yield까지 실행하고 { value, done } 객체 반환
    • return: 호출 시 { value, done: true } 반환 후 종료
    • throw: 호출 시 에러 발생

46.4 제너레이터의 일시 중지와 재개

  • yield 키워드로 실행 중지, next()로 재개
  • next(value): 값을 제너레이터 내부로 전달
  • yield 연속 호출 구조: generator.next() -> yield -> generator.next() -> yield -> ... -> generator.next() -> return

46.5 제너레이터의 활용

  • 이터러블의 구현
    • 무한 이터러블 간결하게 생성 가능 (무한 피보나치 수열 등)
    • 기존 이터레이션 프로토콜 구현보다 간단
  • 비동기 처리
    • yield 표현식을 통해 비동기 흐름을 동기처럼 표현 가능
    • 제너레이터 실행기 필요 (co 라이브러리)

46.6 async/await

  • async 함수
    • async 키워드로 정의, 항상 프로미스 반환
    • 명시적 return 없이도 암묵적으로 프로미스 resolve
    • 클래스의 constructor 메서드는 사용 불가
  • await 키워드
    • await: 프로미스가 완료될 때까지 대기
    • 반드시 async 함수 내부에서 사용
  • 에러 처리
    • try...catch문을 사용해 에러 처리 가능
    • 에러 전파 및 처리 명확
    • catch문을 사용하지 않고 에러가 발생하면 reject된 프로미스 반환

 

47장 에러 처리

47.1 에러 처리의 필요성

  • 에러 방치하면 프로그램 강제 종료
  • try...catch문으로 적절히 대응하면 종료 없이 실행 가능
  • 예외 상황(DOM 조작 등)도 에러로 이어질 수 있으므로 방어 코드 필요
    • null 체크, ?. 옵셔널 체이닝 사용 등

47.2 try...catch...finally 문

  • try, catch, finally 세 블록으로 구성
    • try: 실행할 코드
    • catch: 에러 발생 시 실행, 에러 객체가 인자로 전달
    • finally: 에러 발생과 상관 없이 무조건 실행
  • catch 생략 불가, finally 생략 가능

47.3 Error 객체

  • Error 생성자 함수로 에러 객체 생성 가능
    • const error = new Error('invalid');
    • message: 전달된 에러 메시지
    • stack: 콜스택 정보 (디버깅 목적)
생성자 함수 인스턴스
Error 일반적인 에러
SyntaxError 문법 오류
ReferenceError 정의되지 않은 변수 참조
TypeError 타입 불일치
RangeError 허용 범위를 벗어난 값
URIError URI 처리 함수 오류
EvalError eval 함수 오류

47.4 throw 문

  • 에러 객체 생성만으로는 에러가 발생하지 않음
  • throw문으로 명시적 에러 발생 가능
  • throw: catch 블록 실행 트리거

47.5 에러의 전파

  • 콜 스택을 따라 호출자 방향(아래 방향)으로 전파
  • catch되지 않으면 프로그램 강제 종료
  • setTimeout, Promise.then 등 비동기 콜백 함수 내부에서 throw한 에러는 전파되지 않음
    • 전역에서 uncaught되어 종료될 수 있음, 내부에서 try/catch로 직접 처리 필요
  • 에러는 호출자 쪽에서만 처리 가능, 적절한 위치에 catch 구문 필요

 

48장 모듈

48.1 모듈의 일반적 의미

  • 모듈: 재사용 가능한 코드 조각, 일반적으로 기능 단위로 파일 분리
  • 자신만의 파일 스코프(모듈 스코프)를 가지며, 내부 자산은 기본적으로 비공개
  • export 키워드로 선택적 공개 가능
  • import를 통해 export된 자산 재사용 가능

48.2 자바스크립트와 모듈

  • 과거 자바스크립트는 파일 스코프 없이 전역 공유, 모듈 시스템 미지원
  • 여러 script 태그를 사용해도 전역 스코프 공유, 변수 충돌 가능성
  • 문제 해결을 위해 CommonJS(Node.js 기반), AMD 방식 등장

48.3 ES6 모듈(ESM)

  • type = "module" 속성을 가진 <script> 태그로 ESM 로드
  • ESM: 기본적으로 strict mode 적용
  • 모듈 스코프
    • ESM 내부 변수는 전역 스코프에 등록되지 않음
    • 동일한 식별자를 다른 모듈에서 선언해도 충돌 없이 동작
    • 외부 모듈에서 ESM 내 식별자에 접근 불가 -> export 필요
  • export 키워드
    • 변수, 함수, 클래스 등을 외부에 공개 가능
    • 선언 앞에 export 키워드 사용
    • export const pi = Math.PI; export function square(x) { return x * x; }
    • 하단에서 객체처럼 한 번에 export
    • const pi= Math.PI; function square(x) { return x * x; } export { pi, square };
  • import 키워드
    • 다른 모듈이 export한 식별자를 현재 모듈 스코프 내부로 불러오기
    • 기본 사용
    • import { pi, square } from './lib.mjs';
    • 전체 import (as 구문)
    • import * as lib from './lib.mjs'; lib.square(2);
    • 이름 변경 후 import (as 구문)
    • import { square as sq } from './lib.mjs'; sq(2);
    • default export
      • 모듈에서 하나의 값만 export할 때 사용
      • 이름 없이 export, import 시 임의의 이름 사용
        // lib.mjs
        export default x => x * x;
        
        
  // app.mjs
  import square from './lib.mjs';

  square(3); // 9
  ```

 

49장 Babel과 Webpack을 이용한 ES6+/ES.NEXT 개발 환경 구축

49.1 Babel

  • Babel: ES6+/ES.NEXT 코드를 ES5 코드로 변환하여 구형 브라우저 호환성 확보
  • 브라우저가 지원하지 않는 최신 문법 자동 변환
    • 화살표 함수, 지수 연산자 등
  • 브라우저에서 require 함수 미지원
    • Babel은 기본적으로 CommonJS 방식으로 트랜스파일링 (require, exports)
    • 브라우저는 이를 지원하지 않으므로 브라우저 실행 시 에러 발생

49.2 Webpack

  • Webpack: 여러 JS 모듈, 이미지, CSS 등을 하나의 번들 파일로 묶음
  • 모듈 로더 없이 브라우저에서 실행 가능
  • Babel과 함께 사용하여 트랜스파일링 + 번들링