글쓰는쿼카의 PM 여정

4. 콜백함수 - part 2 본문

개발/JavaScript

4. 콜백함수 - part 2

글쓰는쿼카 joymet33 2024. 5. 2. 00:23

0. 기본정보

#스파르타코딩클럽 #부트캠프 #경과훈련일_13일/94일
- 학습주제: 「자바스크립트 종합반」 (4주차)
- 학습내용: 콜백함수

- 특별사항: [팀회의] 자바스크립트 팀과제 - 영화목록 홈페이지 만들기
- 학습일: 2024. 5. 1.


1. 배운 배용 요약 - 콜백함수 기초

2) 콜백 함수의 제어권

(1) 호출시점 - 아래 게시글 참조

https://joymet33.tistory.com/16

 

(2) 인자 - 예시 : map()

- map 메서드를 호출해서 원하는 배열을 얻고자 한다면 정의된 규칙대로 작성해야 함

- 인자(의 순서)까지도 제어권이 콜백 함수를 넘겨받은 코드에게 있음

 

(3) this

- 콜백함수도 함수이기 때문에 this가 전역객체이나 예외사항이 있음

- 제어권을 넘겨받을 코드에게 콜백 함수에 별도로 this가 될 대상을 지정한 경우에는 그 대상을 참조함

// Array.prototype.map을 직접 구현해봤어요!
Array.prototype.mapaaa = function (callback, thisArg) {
  var mappedArr = [];

  for (var i = 0; i < this.length; i++) {
    // call의 첫 번째 인자는 thisArg가 존재하는 경우는 그 객체, 없으면 전역객체
    // call의 두 번째 인자는 this가 배열일 것(호출의 주체가 배열)이므로,
		// i번째 요소를 넣어서 인자로 전달
    var mappedValue = callback.call(thisArg || global, this[i]);
    mappedArr[i] = mappedValue;
  }
  return mappedArr;
};

const a = [1, 2, 3].mapaaa((item) => {
  return item * 2;
});

console.log(a);

 


2. 팀프로젝트 활동 내용

1) 홈페이지 구현할 기능 작성 - 기능 명세표

더보기
(출처: [React] 5기 docs / ... Undefined(B-09조) 노션 페이지)

2) 팀 규칙 정하기 - github 작성법, 코드 컨벤션

더보기

우리 팀의 github 작성법(브랜치/커밋 롤)

(출처: [React] 5기 docs / ... Undefined(B-09조) 노션 페이지)

 

우리 팀의 코드 컨벤션

(출처: [React] 5기 docs / ... Undefined(B-09조) 노션 페이지)

3) 각 기능별 역할 정하기 - 본인: 메인페이지 검색창의 유효성 검사 구현

더보기

[참고] 팀동료가 직접 작성한 코딩 - 추후 밴치마킹 예정

- 기능: 영화 카드 리뷰 작성 시 유효성 검사

- 조건: userName는 '두 글자 이상~'

           password는 '특수문자 포함한 8자 이상~'

          review는 '10자 이상~'

const reviewForm = document.querySelector(".review__form");
const reviewContainer = document.querySelector(".review__container");

const handleSubmit = (e) => {
  let review = {};
  let isValid = true;
  let errorMessage = "";
  const reviewInputs = document.querySelectorAll("input");
  e.preventDefault();
  reviewInputs.forEach((input) => {
    const value = input.value.trim();
    switch (input.id) {
      case "username":
        if (value.length < 2) {
          isValid = false;
          errorMessage = "작성자 두 글자 이상~";
        }
        break;
      case "password":
        if (value.length < 8 || !/[!@#$%^&*(),.?":{}|<>]/.test(value)) {
          isValid = false;
          errorMessage = "비밀번호는 특수문자를 포함한 8자 이상~";
        }
        break;
      case "review":
        if (value.length < 10) {
          isValid = false;
          errorMessage = "리뷰 10자이상~";
        }
        break;
    }
    if (isValid) {
      review[input.id] = value;
    }
  });

  if (!isValid) {
    alert(errorMessage);
    return;
  }
  review = { ...review, movieId: "/" };
  const id = Date.now();

  localStorage.setItem(id, JSON.stringify(review));
  displayReview();
};

const handleDelete = (e) => {
  if (e.target.className === "delete__btn") {
    const localStorageKey = e.target.dataset.key;
    localStorage.removeItem(localStorageKey);
    const toBeDeleted = document.querySelector(
      `.review__row[data-key="${localStorageKey}"]`
    );
    toBeDeleted.remove();
  }
};

const displayReview = () => {
  reviewContainer.innerHTML = "";
  const keys = [];
  for (let i = 0; i < localStorage.length; i++) {
    keys.push(localStorage.key(i));
  }
  const sortedKeys = keys.map(Number).sort((a, b) => a - b);
  sortedKeys.forEach((key) => {
    {
      const reviewContent = JSON.parse(localStorage.getItem(key));
      const { username, review } = reviewContent;
      const reviewRow = document.createElement("li");
      reviewRow.setAttribute("class", "review__row");
      reviewRow.setAttribute("data-key", key);
      reviewRow.innerHTML = `${username}: ${review}
        <button class="delete__btn" data-key=${key}>❌</button>
        `;
      reviewContainer.appendChild(reviewRow);
    }
  });
};

reviewForm.addEventListener("submit", handleSubmit);
reviewContainer.addEventListener("click", handleDelete);

displayReview();

// 유효성 검사
// localStorage 받아올때 순서 정렬하기
// 수정기능

 


3. 오늘의 회고

- 칭찬: 팀동료(김○훈 님) 직접 작성한 코딩에 대해 딥(?) 해석 및 풀이 요청한 것

- 반성: 새벽예배 후 컨디션 조절 실패

- 보충: JS문법 종합 + 개인프로젝트 + 팀프로젝트 = 3가지 병행