영광의 시대!/2022 개발자의 품격 부트캠프 1기

[개발자의품격][부트캠프][1기][11차시] JavaScript 주요 포인트 #14 | 고급 문법 - Error, Strict Mode, Regular Expression

DandyNow 2022. 2. 15. 12:13
728x90
반응형

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는 모든 메일 서버를 완벽하게 체크하지는 못하지만 유용하다.

728x90
반응형