[개발자의품격][부트캠프][1기][11차시] JavaScript 주요 포인트 #14 | 고급 문법 - Error, Strict Mode, Regular Expression
JavaScript 주요 포인트 #14
Error
컨트롤할 수 없는 영역은 try...catch 문으로 작성해야 한다.
예를 들어 기상청 날씨 정보를 페이지 우측 상단에 보여준다면,
기상청 서버가 다운되었을 때 정보를 받아 올 수 없게 된다.
이러한 장애로 인해 시스템 전체가 다운되면 안되기 때문에 예외처리해주어야 한다.
try...catch
<script>
try {
console.log("아직 에러가 없어요");
num; // 고의로 에러를 만들었다.
} catch (error) {
console.log("try...catch 구문 밖의 코드");
}
// ------- 출력 결과 --------
// 아직 에러가 없어요
// try...catch 구문 밖의 코드
// --------------------------
</script>
<script>
try {
console.log("아직 에러가 없어요");
num; // 고의로 에러를 만들었다.
console.log("에러 다음 코드"); // 에러 다음 코드는 실행하지 않는다.
} catch (error) {
console.log(error); // ReferenceError: num is not defined(정보성으로 메시지를 보여준다)
}
console.log("try...catch 구문 밖의 코드");
// ------------ 출력 결과 ------------
// 아직 에러가 없어요
// ReferenceError: num is not defined
// try...catch 구문 밖의 코드
// -----------------------------------
</script>
<script>
try {
console.log("아직 에러가 없어요");
getWheather(); // ReferenceError(참조할 함수, 변수가 없을 때)
console.log("에러 다음 코드");
} catch (error) {
console.log(error);
}
console.log("try...catch 구문 밖의 코드");
// --------------- 출력 결과 -----------------
// 아직 에러가 없어요
// ReferenceError: getWheather is not defined
// try...catch 구문 밖의 코드
// -------------------------------------------
try {
console.leg("아직 에러가 없어요"); // TypeError
console.log("에러 다음 코드");
} catch (error) {
console.log(error);
}
console.log("try...catch 구문 밖의 코드");
// --------------- 출력 결과 -----------------
// 아직 에러가 없어요
// TypeError: console.leg is not a function
// try...catch 구문 밖의 코드
// -------------------------------------------
try {
console.leg("아직 에러가 없어요"); // TypeError
console.log("에러 다음 코드");
} catch (error) {
console.log(error);
}
console.log("try...catch 구문 밖의 코드");
// --------------- 출력 결과 -----------------
// TypeError: console.leg is not a function
// try...catch 구문 밖의 코드
// -------------------------------------------
try {
let n = 3;
n.substring(0, 3); // TypeError
} catch (error) {
console.log(error);
}
console.log("try...catch 구문 밖의 코드");
// --------------- 출력 결과 -----------------
// TypeError: console.leg is not a function
// try...catch 구문 밖의 코드
// -------------------------------------------
// SyntaxError는 코드 실행전에 IDE에서 표시된다.
// try {
// console.leg("아직 에러가 없어요"; // SyntaxError
// } catch (error) {
// console.log(error);
// }
// console.log("try...catch 구문 밖의 코드");
</script>
<script>
try {
setTimeout(() => {
getWheather();
}, 1000);
} catch (error) {}
// -------------------- 출력 결과 ------------------------
// Uncaught ReferenceError: getWheather is not defined...
// -------------------------------------------------------
// setTimeout 내에 try...catch를 넣어야 예외 처리된다.
setTimeout(() => {
try {
getWheather();
} catch (error) {}
}, 1000);
</script>
<script>
try {
getWheather();
} catch (error) {
// 에러를 구분하여 작성 가능하지만, 실무에서는 에러별로 구분해서 작성할 일은 잘 없었다.
console.log(error.name); // ReferenceError
console.log(error.message); // getWheather is not defined
if (error instanceof ReferenceError) {
} else if (error instanceof TypeError) {
}
// -------------------------- finally를 쓰는 이유 ------------------------------
// node.js에서 물리적 파일 읽고 쓰기할 때 파일이 열려있는 경우 파일을 닫아야 한다.
// 일반적으로 finally에서 그런 처리를 한다.
// 열려있는 파일을 닫아 주어야 다른 사람이 접근할 수있다.
// 그 때는 반드시 finally를 써야한다.
// 가독성을 위해서도 쓴다.
// -----------------------------------------------------------------------------
} finally {
console.log("에러가 나든 안나든 실행");
}
// -------- 실행 결과 ---------
// ReferenceError
// getWheather is not defined
// 에러가 나든 안나든 실행
// ----------------------------
</script>
<script>
// 에러가 아니지만 강제로 에러를 발생시킬 수 있다.
// 실무에서 사용할 일은 거의 없었다고 한다.
let x = "";
try {
if (x === "") {
throw "empty"; // catch로 던진다.
}
if (x !== "") {
// x가 비어있지 않은 경우 실행해야 될 코드를 여기에 작성한다.
}
} catch (error) {}
</script>
Strict Mode(엄격 모드)
ES5에서 추가된 기능이다.
<script>
"use strict"; // 엄격 모드
x = "3";
// -------------- 출력 결과 --------------------
// Uncaught ReferenceError: x is not defined...
// --------------------------------------------
// 함수 내에서 사용하면 그 함수만 엄격한 모드를 쓸 수 있다.
function myFunction() {
"use strict"; // 엄격 모드
y = 2;
}
myFunction();
// --------------------- 출력 결과 ---------------------------
// Uncaught ReferenceError: y is not defined at myFunction...
// ----------------------------------------------------------
</script>
정규 표현식(Regular Expression)
MDN Web Docs에서 필요할 때마다 정규식을 찾아볼 수 있다. 문자열 안에서 내가 원하는 특정한 패턴을 찾아내는 기술이 정규식이다. 정규식을 사용하면 수많은 코드를 써서 해결해야 하는 문제를 간단히 해결할 수 있다. 웬만한 정규식 패턴은 구글 검색으로 찾을 수 있다. 하지만 정규식을 충분히 공부하여 능숙하게 사용하는 것이 매우 중요하다.
<script>
let str = "Hello World, World, World";
let str2 = str.replace(/World/gi, "World!"); // g: 전역 검색, i: 대소문자 구분 없이 검색
console.log(str2);
// -------- 출력 결과 ---------
// Hello World!, World!, World!
// ----------------------------
</script>
<script>
// 정규식 만드는 2가지 방법
let str = "Hello World, World, World";
const regext = /World/; // 1. 슬래시로 감싸기
const regexp2 = new RegExp("World"); 2. 생성자 함수 사용(정규식 패턴이 변경될 수 있거나, 정규식 패턴을 동적으로 적용해야 하는 경우)
console.log(regext.test(str)); // test 함수는 찾고자 하는 문자가 있는지 찾다.
console.log(str.search(regext)); // search 함수는 주소값을 찾아 준다(복잡한 문자열).
console.log(str.indexOf("World")); // indexOf 함수는 주소값을 찾아 준다(단순한 문자열).
// -- 출력 결과 --
// true
// 6
// 6
// ---------------
</script>
<script>
str = "123abc456def";
// [0-9] : 숫자 0~9
// /g : 전역 검색
// {2} ; 연속된 숫자 2자리
const regexp3 = /[0-9]{2}d/g; // ['56d'] 연속된 숫자 2자리와 d가 결합된 모든 경우를 찾는다.
let result = str.match(regexp3); // match 함수는 배열로 만들어 준다.
console.log(result);
// -- 출력 결과 --
// ['56d']
// ---------------
</script>
전화번호를 "01011112222"와 같이 쓸 수 있겠지만 가독성 좋지 않다. 하이픈을 붙이더라도 문자 메시지 발송 외부 서비스들에서 정상적으로 처리하기 때문에 굳이 하이픈을 포함하고 있는 번호를 쓰지 않을 이유는 없다. DB에서 관리하는 데이터는 한 가지 패턴으로 데이터가 들어오도록 해야 한다. 어떤 방식이든 한 방식이 맞다.
<script>
let tel = "abc010-1111-2222"; //
// 전화번호 체크하는 정규식
// const regexp4 = /\d{3}-\d{4}-\d{4}/; // [0-9]와 \d는 같은 의미이다.
// 위 정규식 표현으로는 문자가 섞인 전화번호를 체크할 때 문제가 된다(예: "abc010-1111-2222"가 true가 됨).
const regexp4 = /^\d{3}-\d{4}-\d{4}$/; // ^시작은 숫자, $ 종료는 숫자 4자리
console.log(regexp4.test(tel)); // false
// -- 출력 결과 --
// false
// --------------
</script>
최근에는 이메일 인증하기 때문에 정확하게 입력하지만 이메일 주소가 정상적인지 확인해야 할 필요가 있다. 특히 코엑스 콘퍼런스의 현장등록의 경우 종이에 적어 제출한다. 이때 정확하게 적지 않는 경우가 많다. 정보를 수집하는 입장에서는 사용자 정보가 정확해야 한다. 이때 정규식을 이용해 체크할 수 있다.
<script>
let email = "jem@aaa.c";
// [a-z]+ : 소문자가 하나 이상
// \d* : 숫자가 0개 이상
// ([a-z]+\d*)+ : 소문자 하나 이상이면서 숫자 0개 이상)
// \.? : "."이 1개 이거나 없다(이메일 명으로 .을 하나 이하 허용하는 경우가 있다). "."은 정규식 기능이기 때문에 문자화 하기위해 "\"를 붙인다.
// [a-z]+ : 소문자 하나이상
// @ : "@"는 반드시 있어야한다. "@"는 정규식 기능이 아니기 때문에 "\"를 붙이지 않아도 된다.
// [a-z]+ : 소문자 하나이상
// (\.[a-z]{2,3})+ : 하나 이상
// $ : 앞의 패턴으로 종료
const regex5 = /^([a-z]+\d*)+(\.?[a-z]*)+@[a-z]+(\.[a-z]{2,3})+$/; // 이메일의 시작은 알파벳 a~z, + 는 한개 이상, *는 0개 이상,
console.log(regex5.test(email));
// -- 출력 결과 --
// false
// --------------
</script>
이탈리아의 한 회사는 이메일 정보를 입력하면 실제로 존재하는 이메일인지 확인하는 애플리케이션을 서비스하고 있다. 거의 모든 메일서버를 다 체크해 낸다. 이 처럼 기술 하나만으로도 먹고 살 수 있는 아이디어가 많다. 생각보다 단순한 생각에서 서비스가 만들어질 수 있다. 이 제품과 유사한 무료 npm 모듈이 있다. email-existence는 모든 메일 서버를 완벽하게 체크하지는 못하지만 유용하다.