rustandbone Developer

JavaScript_모듈, 유틸 함수 등

테킷 멋쟁이사자처럼 JavaScript

인트로

자바스크립트 강의 마지막 주차에 접어들었다. 지난주 목요일부터 모듈에 대해 공부하고 있다. 기존 자바스크립트 코드 짜는 것과는 사뭇 다른 것이 있다. export, import, 유틸 함수 만들기 등, 유용한 부분에 대해 많이 학습했다.

html, js

  • html
    • html에는 main.jstype="module"이라고 명시해주면 된다. js 파일에도 자동으로 use strict 모드가 적용된다.
<script src="./main.js" type="module"></script>
  • index.js
    • 메인이 되는 index.js 파일에는 각 세부 폴더 index의 총 집합이다. 때문에 main.js에서는 ./lib/index.js 링크에서 폴더별로 나누어 만들어둔 모듈을 원하는 대로 모두 가져와 사용할 수 있다.
    • 원하는 모듈만 가져와 사용할 수 있고, 전역이 오염될 걱정을 할 필요가 없다는 장점이 있다. 함수 뿐만이 아니라 원하는 객체, 배열 등 모두 만들어 export 할 수 있다.
//./lib/index.js
export * from "./dom/index.js";
export * from "./error/index.js";
export * from "./math/index.js";
export * from "./utils/index.js";
export * from "./animation/index.js";

// ./lib/dom/index.js
export * from "./attr.js";
export * from "./bindEvent.js";
export * from "./clearContents.js";
export * from "./css.js";
export * from "./getNode.js";
export * from "./insert.js";
export * from "./showAlert.js";
export * from "./endScroll.js";
//main.js
import {
  attr,
  clearContents,
  diceAnimation,
  endScroll,
  getNode,
  getNodes,
  insertLast,
} from "./lib/index.js";

유틸 함수

자주 사용하는 함수들은 유틸 함수로 만들어 사용한다. 유틸 함수를 많이 만들었는데, 각 기능을 당연히 알아 사용할 줄 알아야겠다. 또한 자주 쓴다 싶으면 함수로 만들어버리는 것도 좋겠다. 몇 개를 소개한다.

  • getNode 함수
    • 단연 많이 쓰인다. querySelector하는 함수이고, querySelectorAll 하는 함수도 있다.
export function getNode(node) {
  if (typeof node !== "string") {
    throw new Error("getNode 함수의 인수는 문자 타입이어야 합니다");
  }

  return document.querySelector(node);
}
  • addClass
    • 선택한 요소에 클래스를 더하는 함수. 제거하는 함수도 있고, 클래스를 토글하는 함수도 있다.
export function addClass(node, className) {
  if (typeof node === "string") node = getNode(node);

  if (typeof className !== "string") {
    throw new TypeError(
      "addClass 함수의 두 번째 인수는 문자 타입 이어야 합니다."
    );
  }

  node.classList.add(className);
}
  • setCss
    • CSS 속성 set하는 함수. getter 함수도 있다. 줄여서 css함수를 만들어서 value를 전달하면 set, 하지 않으면 get하도록 했다.
function setCss(node, prop, value) {
  if (typeof node === "string") node = getNode(node);
  if (!(prop in document.body.style)) {
    throw new SyntaxError(
      "setCss 함수의 두 번째 인자인 prop이 유효한 css 속성이 아닙니다."
    );
  }
  if (!value) {
    throw new SyntaxError("setCss 함수의 세 번째 인자는 필수값입니다.");
  }
  node.style[prop] = value;
}
  • setAttr
    • 속성 set 하는 함수. css 함수와 유사하게 get, set 하는 함수가 있으며 전달 인자 차이로 구분하도록 설정했다.
export function setAttr(node, property, value) {
  if (typeof node === "string") {
    node = getNode(node);
  }

  if (!node[property] && property !== "class" && property !== "title") {
    node.dataset[property] = value;
    return;
  }

  node.setAttribute(property, value);
}
  • insertLast
    • insertAdjacentHTML 함수 사용해 각 옵션 별로 4가지로 나누어 함수를 만들었다. 그중 가장 많이 쓰이는 요소 마지막에 내용 추가하는 함수.
export function insertLast(node, text) {
  if (typeof node === "string") node = getNode(node);

  if (node.nodeType !== document.ELEMENT_NODE) {
    throw new ReferenceError(
      "insertLast 함수의 첫 번째 인수는 ELEMENT NODE이어야 합니다."
    );
  }
  node.insertAdjacentHTML("beforeend", text);
}
  • clearContents
    • 함수 이름답게 요소 안의 내용은 ‘’ 빈칸으로 만들어준다.
export function clearContents(node) {
  if (typeof node === "string") node = getNode(node);
  if (node.nodeName === "INPUT" || node.nodeName === "TEXTAREA") {
    node.value = "";
    return;
  }

  node.textContent = "";
}

로직 구현

지난주부터 계산기, 오늘은 주접생성기, 랜덤 다이스 같은 토이 프로젝트를 만들었다.

// 랜덤 다이스
// [phase-1]
// 1. dice animation 불러오기
// 2. 주사위 굴리기 버튼을 클릭하면 diceAnimation이 실행될 수 있도록
//    - 주사위 굴리기 버튼 가져오기
//    - 이벤트 핸들러 연결
//    - 애니메이션 코드 작성
// 3. 애니메이션 토글 제어
// 4. 클로저 + IIFE 를 사용한 변수 보호

// [phase-2] 레코드 리스트 control / view
// 1. 주사위가 멈추면 기록/초기화 버튼 활성화
// 2. hidden 속성 제어하기
//    - 기록 버튼 이벤트 바인딩
//    - hidden 속성 false 만들기
//    - 초기화 버튼 이벤트 바인딩
//    - hidden 속성 true 만들기
// 3. 주사위 값을 가져와서 렌더링
// 4. 스크롤 위치 내리기
// 5. 함수 분리

// [phase-3] 초기화 시키기

다른 프로젝트도 마찬가지였지만, 랜덤 다이스의 경우처럼 구현을 위해 단계별 phase를 생각하고 그에 맞게 구현했다. 기능이 작동하도록, 예외 처리 작동해서 오류가 나지 않도록, 빈틈없이 로직을 phase 별로 짜고 구현하는 능력이 중요하겠다.
코딩 테스트 문제를 풀면서, 문제 이해, 로직, 구현으로 이어지는 훈련이 좋았던 듯 하다. phase를 치밀하게 잘 짜고, 그대로 구현하는 능력을 기를 필요가 있겠다.