에러 처리
console.log('[Start]');
foo(); // ReferenceError: foo is not defined
// 발생한 에러를 방치하면 프로그램은 강제 종료된다.
// 에러에 의해 프로그램이 강제 종료되어 아래 코드는 실행되지 않는다.
console.log('[End]');
에러가 발생하지 않는 코드를 작성하는 것은 불가능하며, 에러를 방치하면 프로그램은 강제 종료된다
// DOM에 button 요소가 존재하지 않으면 querySelector 메서드는 에러를 발생시키지 않고 null을 반환한다.
const $button = document.querySelector('button'); // null
$button.classList.add('disabled');
// TypeError: Cannot read property 'classList' of null
당장 에러가 발생하지 않더라도 예외적인 상황에 대응하지 않으면 에러로 이어질 수 있다
console.log('[Start]');
try {
// 실행할 코드(에러가 발생할 가능성이 있는 코드)
foo();
} catch (err) {
// try 코드 블록에서 에러가 발생하면 이 코드 블록의 코드가 실행된다.
// err에는 try 코드 블록에서 발생한 Error 객체가 전달된다.
console.error(err); // ReferenceError: foo is not defined
} finally {
// 에러 발생과 상관없이 반드시 한 번 실행된다.
console.log('finally');
}
// try...catch...finally 문으로 에러를 처리하면 프로그램이 강제 종료되지 않는다.
console.log('[End]');
보통 try…catch…finally 문으로 에러를 처리할 수 있다
const error = new Error('invalid');
Error 생성자 함수로 에러 객체를 생성할 수 있다
try {
// 에러 객체를 던지면 catch 코드 블록이 실행되기 시작한다.
throw new Error('something wrong');
} catch (error) {
console.log(error);
}
에러 객체를 생성한다고 에러가 발생하지는 않고 try 코드 불록에서 throw 문으로 에러 객체를 던져야 한다
const foo = () => {
throw Error('foo에서 발생한 에러'); // ④
};
const bar = () => {
foo(); // ③
};
const baz = () => {
bar(); // ②
};
try {
baz(); // ①
} catch (err) {
console.error(err);
}
throw된 에러를 캐치하지 않으면 캐치될 때까지 호출자 방향으로 전파된다
모듈
모듈(Module)이란 애플리케이션을 구성하는 개별적 요소로서 재사용 가능한 코드 조각을 뜻하며, 일반적으로 기능을 기준으로 파일 단위로 분리한다. 이 때 모듈이 성립하려면 자신만의 파일 스코프(모듈 스코프)를 가질 수 있어야 한다 (캡슐화)
- export: 모듈은 공개가 필요한 자산에 한정해 명시적으로 선택적 공개가 가능
- import: 모듈이 공개한 자산 중 일부 또는 전체를 선택해 자신의 스코프 내로 불러들여 재사용
자바스크립트는 사실상 표준인 CommonJS를 채택해 모듈 시스템을 점진적으로 지원하게 되었다
<script type="module" src="app.mjs"></script>
ES6에 추가된 ES6 모듈(ESM)은 script 태그에 module 어트리뷰트와 mjs 확장자 파일을 사용한다
<!DOCTYPE html>
<html>
<body>
<script type="module" src="foo.mjs"></script>
<script type="module" src="bar.mjs"></script>
</body>
</html>
각각의 모듈 파일은 독자적인 모듈 스코프를 가지며 하나의 전역을 공유하지 않는다
// lib.mjs
// 변수의 공개
export const pi = Math.PI;
// 함수의 공개
export function square(x) {
return x * x;
}
// 클래스의 공개
export class Person {
constructor(name) {
this.name = name;
}
}
export 키워드로 다른 모듈들이 재사용할 수 있도록 공개할 수 있다
* 마지막에 객체로 묶어서 한 번에 export 가능
* default 키워드로 이름 없이 하나의 값 export 가능 / 원하는 이름으로 import
// app.mjs
// 같은 폴더 내의 lib.mjs 모듈이 export한 식별자 이름으로 import한다.
// ESM의 경우 파일 확장자를 생략할 수 없다.
import { pi, square, Person } from './lib.mjs';
console.log(pi); // 3.141592653589793
console.log(square(10)); // 100
console.log(new Person('Lee')); // Person { name: 'Lee' }
import 키워드로 다른 모듈에서 공개한 식별자를 자신의 모듈 스코프 내부에서 로드할 수 있다
* 애스터리스크(*)로 전체 식별자 import 가능
* as 키워드로 이름을 변경해 import 가능
<!DOCTYPE html>
<html>
<body>
<script type="module" src="app.mjs"></script>
</body>
</html>
이 경우 의존성(dependency)을 가지는 진입점(entry point)을 script 태그로 로드해야 한다
본 내용은 위키북스의 '모던 자바스크립트 Deep Dive'를 바탕으로 작성되었습니다.
'Languages > JavaScript' 카테고리의 다른 글
[TIL] 자바스크립트(node.js)로 백준을 풀어보자 (0) | 2023.01.30 |
---|---|
[TIL] MVC 패턴을 알아보자 (0) | 2022.12.15 |
[HUFS/GnuVil] #25 제너레이터와 async/await (0) | 2022.11.29 |
[HUFS/GnuVil] #24 프로미스 (0) | 2022.11.29 |
[우아한테크코스/프리코스] #4 다리 건너기 (0) | 2022.11.23 |