본문 바로가기

JavaScript

[모던자바스크립트 DeepDive] 47장 에러 처리 & 48장 모듈

본 글은 자바스크립트 스터디를 진행하면서 [모던자바스크립트 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'; // 맘대로 작명
728x90
반응형