Error
try-catch
try{} catch(){}
를 사용하면 에러가 발생하더라도 스크립트가 계속 진행된다.
async function myFun(){
try{
// 이 영역에서 실행한 구문이 문제가 생긴다면
}
catch(e){
// 이곳에서 error를 처리한다.
}
}
<script>
try {
console.log("try블럭 시작");
throw new SyntaxError("구문이 틀렸어요: 다시 작성하세요");
console.log("try블럭 끝")
}
catch(err){
console.log(err.name);
console.log(err.message);
}
finally{
console.log("항상 실행");
}
console.log("계속동작");
</script>
Error.
catch(e){
console.log(e.name);
// ReferenceError, TypeError...
console.log(e.message);
// Expected property name or '}' in JSON at position 1...
}
Error
런타임 오류가 발생되면 생성
Error
는 브라우저마다 prototype
이 다를 수 있지만 message
는 보통 포함한다.
new Error('message')
에러는
new Error()
나Error()
로도 직접 생성할 수 있다.
TypeError
보통 값이 기대하던 자료형이 아니라서 연산을 할 수 없을 때 발생하는 오류
new TypeError(message)
const error = 0;
error(); // TypeError: error is not a function
error += 1; // TypeError: Assignment to constant variable.
// const로 선언된 변수는 재할당 할 수 없다 !
- 변수 타입과 상관없는 명령을 실행할 때
- 함수가 아닌데 함수처럼 호출할 때
- const로 선언된 변수에 재할당을 시도할 때
.
.
.등에 발생하는 에러이다.
SyntaxError
javascript가 요구하는 규칙대로 프로그램을 작성하지 않을 경우 발생
new SyntaxError(message)
console.log("SyntaxError"
console.log
호출할 때 )
를 누락하면 SyntaxError: missing ) after argument list
가 출력된다.
ReferenceError
존재하지 않는 변수를 참조했을 때 발생하는 에러
new ReferenceError(message)
console.log(error); // ReferenceError: error is not defined
if (true) {
let car = 0;
}
console.log(car); // ReferenceError: car is not defined
선언하지 않은 변수를 참조할때 주로 발생
throw new
throw 연산자를 이용해서 언제든지 에러를 반환할 수 있다.
(반드시 Error 객체를 반환해야하는 것은 아니다.)
throw 123;
throw '123';
throw new Error('123');
try{
throw new ErrorName ("message")
}
try문 내에서 이 구문을 만나면 에러를 만난 것과 같이 catch문이 실행된다.
이때, 지정한 에러의 message가 catch(e){}의 이벤트값 e의 .message로 반환된다.
async
/ await
에러async
/ await
문법은 try-catch
로 에러를 확인할 수 있다.
let async_await_error = async () => {
throw new Error('async');
}
try {
await async_await_error();
} catch(e) {
console.error(e.message);
// async
}
Module
자바스크립트 모듈
- 모듈은 코드를 관리하는 가장 작은 단위
- 모듈을 이용하면 코드관리와 재활용이 편리해진다.
- es6부터 import, export 문이 추가되었다.
- 자바스크립트 파일을 분리하고 사용하는 기술
import
import
지시자를 붙이면 다른 외부 모듈을 가지고 와서 사용할 수 있다.
import
: 가져오기(모듈 사용하기)
import 이름 from 파일이름.js
export
export
지시자를 변수나 함수 앞에 붙이면 다른 외부 모듈에서 해당 변수나 함수를 import
해서 사용할 수 있다.
export
: 내보내기
index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<script type="module">
import{ log } from "./log.js";
// log.js에서 export 지정된 함수 중 log 함수만 import하겠다.
log("")
// log 함수 실행
import { log, conGreen, error } from "./log.js";
// log.js에서 export로 지정된 함수 중 이름이 같은 함수를 import;
log(conGreen);
</script>
</body>
</html>
log.js
export function log(message){
console.log(message);
}
export function error(message){
console.error(message)
}
export const conGreen = "그린컴퓨터입니다.";
이렇게
import
로 불러export
했던 함수 / 변수를 사용할 수 있다.
Component
프로그래밍에 있어 재사용이 가능한 각각의 독립된 모듈
index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<div id="app">
</div>
<script src="./src/Main.js" type="module"></script>
</body>
</html>
App.js
import Component from "./components/Component.js";
import ContentInput from "./components/ContentInput.js";
import Lists from "./components/Lists.js";
export default class App extends Component{
setup(){
this.state = {
students: [
{
no: 1,
contents: "stu1",
active: true
},
{
no: 2,
contents: "stu2",
active: false
},
{
no: 3,
contents: "stu3",
active: false
},
]
}
console.log(this);
}
template(){
return `
<div id="contentAdd"></div>
<div id="studentLists"></div>
<div id="viewBtn"></div>
`;
}
mounted(){
const { students } = this.state;
const { addStudent, deletestudent } = this;
const contentAppender = document.querySelector("#contentAdd");
const stuListDiv = document.querySelector("#studentLists");
new ContentInput(contentAppender, {
addStudent: addStudent.bind(this)
});
new Lists(stuListDiv, { students : students,
deletestudent: deletestudent.bind(this) });
//객체 { target: stuListDiv, props: { students: []} }
}
addStudent(contents){
const { students } = this.state;
// students.map(s=>s.no) => [1,2,3]
//no 중 가장 큰 숫자를 찾아서 1을 더한 값을 할당
const no = Math.max(0, ...students.map(s=>s.no))+1
this.setState({
students: [
...students,
{
no: no,
contents: contents,
active: false
}
]
})
}
deletestudent(no){
const { students } = this.state;
const newStudents = students.filter(stu => stu.no !== no);
console.log(newStudents);
this.setState({ students: newStudents });
}
}
Main.js
import App from "./App.js";
new App(document.querySelector("#app"));
Component.js
//모듈 내보내기
export default class Component {
target;
props;
state;
constructor(target, props){
this.target = target;
this.props = props;
//메소드 호출
this.setup();
this.render();
this.setEvent();
console.log(this);
}
template() { return "" }
render(){
this.target.innerHTML = this.template();
this.mounted();
}
setState(newState){
this.state = { ...this.state, ...newState };
this.render();
}
setup(){};
mounted(){};
setEvent(){};
}
ContentInput.js
import Component from "./Component.js";
export default class ContentInput extends Component{
template(){
return `
<input type="text" class="appender">
`
}
setEvent(){
const { addStudent } = this.props;
this.target.addEventListener("keyup", (e)=>{
console.log(e);
if(e.key !== "Enter") return;
addStudent(e.target.value);
})
}
}
Lists.js
import Component from "./Component.js";
export default class Lists extends Component{
template(){
const { students } = this.props;
console.log(students);
return `
<ul>
${students.map(stu=>`<li data-no="${stu.no}">
${stu.contents}
<button>${stu.active? '비활성': '활성'}</button>
<button class="deleteBtn" data-no="${stu.no}">삭제</button>
</li>`).join("")}
</ul>
`
}
setEvent(){
const { deletestudent } = this.props;
this.target.addEventListener("click", (e)=>{
if(e.target.classList.contains('deleteBtn')){
console.log("deleteBtn입니다.");
//배열에서 삭제하기
console.dir(e.target); //log가 아닌 dir로 찍으면 자세히 볼 수 있다.
deletestudent(Number(e.target.dataset.no))
}
})
}
}