[프론트엔드 스쿨 6기] 🗓️ 8월8일

유동균·2023년 8월 8일
0

프론트엔드 스쿨 6기

목록 보기
32/44
post-thumbnail
post-custom-banner

자바스크립트의 객체지향(OOP)는 OOJS라고 불리기도 한다.

객체 지향 프로그래밍

life cycle?


class 정의

  • 사용자가 인스턴스를 생성할 때 매개변수new CountUpButton({ count: 3 })를 전달해 class 내부 계산에 의해 값을 수정할 수 있지만, 사용자가 직접 class 내부의 값을 수정할 수는 없다.
  • count: props.count ?? 0 nulish 병합 연산자: props로 전달된 객체에 count라는 property가 있다면(truthy) 그 값을 사용하고 아니라면(falthy) 0을 사용.

    a ?? b: anull도 아니고 undefined도 아니면 a, 그 외의 경우는 b

button render

  • render() 내부에서 button을 생성하고, 생성된 buttonreturn
  • return으로 반환된 buttonmount(container)에서 전달받은 containerappend, container?.append?.(this.render())
    • optional chaining ?.
      • obj?.propobj가 존재하면 obj.prop을 반환하고, 그렇지 않으면 undefined를 반환함
      • obj?.[prop]obj가 존재하면 obj[prop]을 반환하고, 그렇지 않으면 undefined를 반환함
      • obj?.method()obj가 존재하면 obj.method()를 호출하고, 그렇지 않으면 undefined를 반환함
  • inserAdjacentHtml를 사용하는 방법
    위의 코드에서 inserAdjacentHtml 대신 append를 사용한 이유는 위에서 생성한 button이 HTMLElement Node이기 때문이다.
    그렇다면 inserAdjacentHtml를 사용해 버튼을 생성하는 방법은?

객체 합성


class에 의해 생성된 인스턴스에 전달된 매개변수는 class내부에서 계산된다.

static defaultProps = {
  count: 0,
  step: 1,
  max: 10,
};

이때 class의 static field의 defaultProps를 ... spread syntax을 통해 전개하고, 사용자가 전달한 props 또한 전개해 새로운 객체로 생성한다.
이때 겹치는 propert가 존재한다면 뒤에 오는 property의 값으로 덮어 써진다.

이벤트 연결

  • render()가 실행되면서 생성된 button 요소에 이벤트를 생성하고 싶다면, bindEvents() 함수를 생성해 이벤트를 실행시키면 된다.
  • 이때 bindEvents()에서는 button에 접근할 수 없는데, private field에 #button을 등록해 render()가 실행되면서 button#button에 할당해 bindEvents()#button 즉, button에 접근 가능하도록 한다.
  • bindEvents()render()가 실행되면서 실행되도록 하면서 이벤트의 주체는 this.#button이 되도록 한다.

웹 컴포넌트

웹 컴포넌트는 개발자가 직접 정의한 요소를 뜻하고, 이를 이용해 재사용 가능하게 만든다.

웹 컴포넌트 생성

사용자가 정의한 <count-up-button> 사용하기


1. class 생성 및 customElements 정의

  • customElements를 정의하는데 첫 번째 인자인 이름은 반드시 케밥 케이스로 작성해야하고,
  • 두 번째 인자는 생성자 함수가 와야한다.

  1. extends
  • HTMLElement를 상속하여 새로운 사용자 정의 요소를 생성

  1. super()
  • 생성자 내에서 사용되며 부모 클래스의 생성자를 호출하는 동시에, 상속받은 부모 클래스에서 사용할 수 있는 속성 및 메소드를 초기화
  • 즉, HTMLElement 클래스의 생성자가 호출되고, 해당 클래스의 속성 및 메소드를 CountComponent 클래스에서 사용할 수 있도록 해준다.

    extends로 상속받기 위해서는 super()를 반드시 사용해야한다.
  • CountComponent 생성자로 인해 <button>이 출력되고.
    이렇게 CountComponent class는 특정 HTML 구조에 해당하는 사용자 정의 HTMLElement를 만든다.

CustomEvent & dispatchEvent

MDN Web_components

사용하는 이유

  • 커스텀 이벤트를 호출하여 원하는 정보를 detail 프로퍼티로만 전달할 수 있으므로 데이터가 꼬일 일이 없다.
    • 즉, 기본 이벤트를 호출했는지 커스텀 이벤트를 호출했는지 detail 프로퍼티로 구분할 수 있다.
  • 커스텀 이벤트는 트리거 된다
    • 기본 이벤트인 마우스 클릭 이벤트는 클릭이 발생하면 mousedown → mouseup → click 순서로 이벤트가 처리되기 때문에 mousedown 이벤트 핸들러가 끝나기 전에는 click 이벤트 핸들러를 호출할 수 없다.`
    • 하지만, 커스텀 이벤트는 도중에 트리거 되므로 기본 이벤트가 종료되기 전에 커스텀 이벤트를 호출할 수 있다.
      • 기본 이벤트 안에서 커스텀 이벤트를 발생시킬 수 있다
      • 커스텀 이벤트 끝난 후 코드가 실행된다

syntheticEvent이란?

함수형 프로그래밍

  • 함수형 프로그래밍을 사용하는 이유

함수 분리 실습

fetch함수 로직

payload - 전송되는 데이터

function fetchAndRenderAndLogAlbumList() {
  fetch("https://jsonplaceholder.typicode.com/album/1/photos?_start=0&_limit=4")
    .then((response) => response.json())
    .then((data) => {
      dummyDocument.body.innerHTML = `
        <ul class="albumList">
          ${data
            .map(
              ({ albumId, id, title, url, thumbnailUrl }) =>
                `
                <li class="albumItem">
                  <a class="albumLink" href="${url}">
                    <img class="albumThumbnail" src="${thumbnailUrl}" alt="" />
                    <div role="group" class="albumInfo">
                      <strong class="albumTitle">${title}</strong>
                      <span class="albumId">${albumId}</span>
                    </div>
                  </a>
                </li>
              `
            )
            .join("")}
        </ul>
      `;
    })
    .catch((error) => console.error(error.message));
}
fetchAndRenderAndLogAlbumList();

위의 코드를 하나의 함수가 하나의 기능에 집중하게 구성하기

// 데이터 패치(가져오기)
function fetchData(endpoint) {
  // Promise
  return fetch(endpoint)
    .then((response) => response.json())
    .catch((error) => console.error(error.message));
}
// 데이터 기반 렌더링
function renderAlbumList(data, container) {
  container.innerHTML = `
    <ul class="albumList">
      ${data
        // list rendering
        // render lists
        .map(
          ({ albumId, id, title, url, thumbnailUrl }) =>
            `
            <li class="albumItem">
              <a class="albumLink" href="${url}">
                <img class="albumThumbnail" src="${thumbnailUrl}" alt="" />
                <div role="group" class="albumInfo">
                  <strong class="albumTitle">${title}</strong>
                  <span class="albumId">${albumId}</span>
                </div>
              </a>
            </li>
          `
        )
        .join("")}
    </ul>
  `;
  return container;
}
// 로그
function log(container) {
  console.log(container.outerHTML);
}
// 함수 실행
async function run() {
  // 데이터 패치(가져오기)
  const responseData = await fetchData(
    "https://jsonplaceholder.typicode.com/album/1/photos?_start=0&_limit=4"
  );
  // 데이터 기반 렌더링
  const container = renderAlbumList(
    responseData,
    document.getElementById("demo")
  ); // as HTMLDivElement, TS에서 요소로 변경하는 방법
  // 로그
  log(container);
}
run();
post-custom-banner

0개의 댓글