본 글은 자바스크립트 스터디를 진행하면서 [모던자바스크립트 DeepDive] 책을 바탕으로 작성된 글입니다.
47장 에러 처리
에러 처리의 필요성
에러를 방치하면 프로그램은 강제 종료됨
console.log('start'); // 실행
정의되지않은함수(); // 에러
console.log('end'); // 실행 X
try...catch문을 사용하면 강제 종료되지 않는다
console.log('start');
try{
정의되지않은함수();
} catch(err){
console.error(err);
}
console.log('end'); // 실행 O
직접적으로 에러를 발생하는 상황 이외에 간접적인 상황도 존재
const element = document.getElementById('없는id'); // null 할당
element.length; // null에는 프로퍼티가 없으므로 에러
에러를 발생하지 않는 코드를 작성하는 것은 불가능
언제나 에러가 발생할 수 있는 점을 고려하고 이에 대응하는 코드를 작성해야한다.
📙 try...catch...finally문
try{
//에러가 발생할 수 있는 코드
} catch(err){
// try 블록에서 에러가 발생시 실행되는 부분
// err에는 try 블록에서 발생한 에러 객체가 전달됨
} finally{
// 에러가 나던 안 나던 실행되는 부분
}
Error 객체
- Error 생성자 함수로 생성 가능
- 생성자 함수로 생성한 에러 객체는 message와 stack 프로퍼티를 갖음
- message : 생성자 함수에 인수로 전달한 에러 메시지
- stack : 디버깅 목적, (에러를 발생시킨 콜스택의 호출 정보)
- 에러 객체를 생성할 수 있는 생성자 함수는 총 7개
- Error
- SyntaxError
- ReferenceError
- TypeError
- RangeError
- URIError
- EvalError
throw 문
에러 객체를 생성한다고 해서 에러가 발생하는 것은 아님
throw 문으로 에러 객체를 던져야 에러가 발생함
try{
throw new Error('내가만든에러');
} catch(err){
console.error(err); // Error: 내가만든에러
}
에러의 전파
에러는 호출자 방향으로 전파 = 실행 컨텍스트의 아래 방향으로 전파
에러가 발생 했는데 캐치하지 않으면 전파되는데 어디에서도 캐치하지 않으면 강제 종료
const first = () => {
throw new Error('fist's Error');
}
const second = () => {
first();
}
const third = () => {
second();
}
try{
third();
} catch(err){
console.error(err);
}
실행 컨텍스트 스택 : 전역>third>second>first
first에서 에러가 발생했는데 first실행 컨텍스트에서는 에러를 캐치하지 않으니 second로 에러 전파
second -> third -> 전역의 catch문에서 에서 캐치
비동기 함수나 프로미스 후속처리 메서드의 콜백 함수는 호출자가 없다
실행 컨텍스트의 맨 아래이다
에러를 전파할 호출자가 존재하지 않는다
48장 모듈
모듈의 일반적 의미
- 애플리케이션을 구성하는 개별적 요소, 재사용 가능한 코드 조각
- 기능을 기준으로 파일 단위로 분리
- 자신만의 파일 스코프를 갖어야함
- 기본적으로 모듈의 리소스는 비공개지만 비공개면 재사용이 불가능하니 의미가 없음
- 개발 효율성과 유지보수성 향상
export : 공개가 필요한 리소스에 한정하여 명시적으로 선택적 공개
import : 모듈이 공개한 리소스중 일부or전체를 자신의 스코프 내로 불러들인다
자바스크립트와 모듈
원래는 파일 스코프와 ,export,importf를 지원하지 않았다
웹 페이지의 단순한 처리를 위한 언어였으니
클라이언트 사이드 자바스크립트는 script 태그를 통해 외부 파일을 로드할 수 있지만 파일마다 독립적인 스코프를 갖지 않는다
script 태그로 여러 자바스크립트 파일을 로드해도 하나의 전역을 공유함
현재 Node.js는 모듈 시스템을 지원함 -> 파일별로 파일 스코프 갖음
ES6 모듈 (ESM)
IE를 제외한 대부분의 브라우저에서 사용 가능
script 태그에 type="module" 어트리뷰트를 추가하면 됨
파일 확장자는 일반 자바스크립트 파일과 구별을 위해 .mjs 추천
strict 모드 적용이 기본
📙 모듈 스코프
일반 자바스크립트 파일은 script 태그로 분리해 로드해도 하나의 전역이다
//temp1.js
var name = 'Sam';
console.log(window.name);
//temp2.js
console.log(name);
//temp.html
<script src="./temp1.js"></script>
<script src="./temp2.js"></script>
// teml.html의 콘솔창에는 Sam이 두번 찍힌다
//temp.html
<script src="./temp1.js" type="module"></script>
<script src="./temp2.js" type="module"></script>
// 파일 자체 모듈 스코프 제공, var로 선언해도 전역 객체의 프로퍼티가 아님
📙 export 키워드
- export 키워드는 선언문 앞에 사용
- 모든 식별자는 export 가능
export const name = 'Sam';
export function square(x){
return x*x;
}
- 일일히 export 안하고 객체로 구성해서 한번에 가능
//lib.mjs
const name = 'Sam';
function square(x){
return x*x;
}
export {name, square};
📙 import 키워드
- 다른 모듈이 export한 식별자 이름으로 import
- ESM의 경우 파일 확장자 생략 불가
import {name,square} from './lib.mjs';
- 하나의 이름으로 한번에 import하면 객체의 프로퍼티로 할당됨
import * as lib from './lib.mjs';
lib.name; // 'Sam'
lib.square(2); // 4
- 모듈이 export한 식별자 이름을 변경할 수 있음
import {name as N,square as S} from 'lib.mjs';
- 모듈에서 하나의 리소스만 export할꺼면 default 키워드로
// 이름 없이 바로 하거나
export default x=>x*x;
// const,let,var 쓰면 에러
export default const square = x => x*x;
//따로 선언을 하고 export default 이름
const square = x => x*x;
export default square;
- default 키워드로 export한 모듈은 import 할때 {} 없이 이름 지어주면 됨
//lib.mjs
export default x => x*x;
// app.js
import square from './lib.mjs'; // 맘대로 작명
import 제곱 from './lib.mjs'; // 맘대로 작명
'JavaScript' 카테고리의 다른 글
[모던자바스크립트 DeepDive] 46장 제너레이터와 async await (0) | 2023.02.25 |
---|---|
[모던자바스크립트 DeepDive] 45장 Promise (0) | 2023.02.18 |
[모던자바스크립트 DeepDive] 41장. 타이머 & 43장. Ajax (0) | 2023.02.18 |
[모던자바스크립트 DeepDive] 40장 이벤트 (0) | 2023.02.12 |
[모던자바스크립트 DeepDive] 42장 비동기 프로그래밍 (0) | 2023.02.12 |