[TIL] 코드스쿼드 코코아 3주차 - Part 2

Dico·2020년 11월 18일
0

[TIL]

목록 보기
6/13
post-thumbnail

코드스쿼드 코코아과정 3주차 TIL - Part2


Mission 6. 리팩토링과 학습정리

향상된 OOP의 조건만족시키기

지금 구현된 코드가 아래 조건을 만족하는지 체크해보고 코드를 개선해보자.

  • 하나의 클래스(모듈)이 너무 크지 않고 적절한 역할만을 수행.
  • 클래스간의 연결시 결합도가 낮은 편
  • 클래스의 메서드들 역시 자기의 역할에 충실하며 작은 역할만 하는 코드로 구현되어 있음
  • 생성자에서는 객체의 속성을 초기화 하는 역할만 하고 있음

UX향상시키기

지금 구현한 기능 이외에 추가적인 기능을 스스로 기획해서 한 가지 추가한다.
Ex. 수정기능, 날짜별 TODO보기 기능 (날짜별로 한일/할일 레이어가 화면에 여러개 노출), 등.

기술정리 글쓰기

지금까지 배운 내용을 짧은 블로그 또는 마크다운으로 정리하고 공유한다.

  • 구현은 했으나 아직 이해도가 부족한 부분을 찾아서 추가로 학습한다.
  • 글은 기술 종합 정리가 아니고, 자신이 깨달은 경험 위주로 작성하는 것도 좋다.

My Code Review

전체코드보기

직접 실행해보기

  1. 초기에는 전역스코프에 필요한 함수들을 선언하고 호출하면서 웹to-do 프로젝트의 필수 기능들을 구현했었던 반면,
    오늘은 ES6 Class를 사용해 객체 인스턴스를 생성해 같은 기능들을 구현하는 데에 초점을 두고 리팩토링 해보았다.
  2. 마감날짜정보(Due date)를 함께 입력할 수 있는 기능을 추가했다.

📚 그 과정에서 새롭게 알게 된 것들:

Closure변수를 callback함수에 사용하기

버튼에 addEventListener로 콜백함수를 설정해주는 과정에서 문제가 생겼다.
아무리 button에 클릭을해도 콜백함수가 실행이 되지를 않았다.

    addEvent() {
        const button = document.querySelector(".button");
        const inputText = document.querySelector(".task_text");

        button.addEventListener('click', (inputText) => {   📌📌📌
            if (inputText.value === "") {
                alert("입력칸이 비었습니다. 할 일을 입력하세요.");
            } else {
                const currentValue = document.querySelector(".task_text").value;
                this.view.makeNewLi(currentValue);
                this.model.saveNewData();
                inputText.value = "";
            }
        });

    }

계획대로라면 아무런 text가 입력되지 않았을 때 alert창으로 메세지를 띄워줘야하는데, (야속하게도)빈 객체가 잘만 추가 되었다.
debugger로 inputText에 담긴 요소도 확인해보고 console.log도 실행해보았지만, 초기에 문제원인이라고 예상했던 inputText는 정상적으로 요소를 담고 있었다.
한참을 씨름한 결과, addEventListener의 두번째 인자인 화살표함수의 parameter를 ()로 비워두자 실행이 되었다!

클로저(Closure)가 클로저변수를 저장해주기 때문이다.

JavaScript의 클로저(Closure)란, 함수가 선언될 당시 (혹은 생성될 당시) 주변 환경(Lexical Environment)와 함께 갇히는 것을 의미한다.
클로저는 함수가 선언되는 주변 환경과 관련하여 생성되는 개념으로, 실행되는 장소나 시점은 관계가 없다!


그래서 parameter로 전달하지 않아도 콜백함수 내에서 바로 inputText로 가져와서 사용하면 된다.
이제button.addEventListener()함수는 생성될 당시 주변 환경(inputText를 포함해서)을 지속적으로 기억할 수 있기 때문이다.
이 부분을 수정해 밑의 코드로 다시 실행하니 원하는 결과를 얻을 수 있었다❗️

    addEvent() {
        const button = document.querySelector(".button");
        const inputText = document.querySelector(".task_text");

        button.addEventListener('click', () => {    📌📌📌 //(inputText) -> ()
            if (inputText.value === "") {
                alert("입력칸이 비었습니다. 할 일을 입력하세요.");
            } else {
                const currentValue = document.querySelector(".task_text").value;
                this.view.makeNewLi(currentValue);
                this.model.saveNewData();
                inputText.value = "";
            }
        });

    }


In addition to that...

  • CSS 선택자로 요소를 가져올 때 조심해야할 점은, DOM구조(추가되거나 빠지는 등 변경될 수 있는 구조; ex.태그명)에 너무 의존하는 문법을 쓰면 깨질 수 있음.
    그래서 클래스나 아이디처럼 좀 더 의미를 가진 셀렉터를 쓰는 것이 좋음.
  • id는 해당 document에 유일한 요소이기 때문에 id를 쓰는 것이 확실하게 중복을 방지할 수 있지만, 팀마다 회사마다 다른 컨벤션을 따라간다. 일반적으로 class를 많이 씀.
  • 국내 포탈 사이트 등의 소스코드를 볼 때는 ‘모바일 웹’버전으로 볼 것. pc는 예전에 짜놓은 코드가 많아서 보기가 불편하다. 네이밍이나 컨벤션 참고시 볼 것.
  • 보통 HTML요소명은 camelCase보다 _(underbar)를 더 많이 쓰는 편.
  • 폰트 위주로 em, rem을 써보기. em, rem은 반응형 웹에서 의미가 있다.
    어떤 차이가 있는 지 써볼 것. px 쓰기.
  • CSS 사용 시 반드시 알아야 할 키워드:
    #position, #float, #box model(+PLUS: #grid, #flex)
  • float은 좌우배치를 가능하게 한다.
  • 전체적인 화면 layout에는 grid, flex를 쓸 수도 있다.
  • 시각장애인들을 위한 '스크린 리더기'라는 프로그램이 존재한다. 우리가 의미있는 태그를 사용해야하는 이유 중 하나는 이것이 태그를 기준으로 소스코드를 읽어주기 때문이다.
  • li태그(<li>)가 현업에서 상당히 많이 쓰인다.(예상보다 훨씬 더 자주!)
    보편적으로 생각하는 리스트 외에도 갤러리 모양의 사진들도 li태그 씀.
    그룹을 묶어줘서 컨테이너 역할을 하기도함.
    li태그 내부에 div나 a태그가 내부에 들어있기도 함.
  • <클래스를 나눌 때>
    클래스가 큰지 안큰지는 중요하지는 않음.
    응집도가 잘 구성이 되어있는지의 문제.
    현대의 개발은 잘게 나누는 추세.
    역할이 중요, 크기는 크게 중요하지는 않음.
  • 클래스 마다 무엇을 하는지 역할/핵심기능을 “주석(comment)”으로 적어주기.
    todolist를 관리(추가, 삭제, 변경)하는 것이 UI에서의 Model의 역할.
    서비스에서 변경이 되는 데이터(화면이 결정되는)들을 다룸.
    Model은 view와의 의존성은 거의 없어야 한다.
  • 어떤 순서로 호출이 되는가? 클래스간 호출관계를 표현해서 살펴보기(화살표(➡️)로 표현해보기)
    일관된 방법으로 흐른다면 괜찮음. 흐름이 매끄럽고 자연스러운지도 볼 것.
  • 함수명 지을 때 주의사항:
    예를 들어 AddDeleteButton 이라고 함수지으면
    동사 + 동사 + 명사 로 혼선을 줄 수 있음.
    동사가 연달아오면 기능이 어떤 건지 직관적으로 알기가 어렵기 때문에.
    직관적으로 이해할 수 있는 함수 이름을 짓는 것이 아주 중요….!!
  • Add 나 remove 는 데이터를 조작할때 많이 씀.
    화면에 그릴 때는 render라고 표현하는 게 좋다.
  • 너무 긴 정적 데이터는 별도로 따로 분리해서 다른 곳에다가 관리할 수도 있다.
  • addEventListener()에서 콜백 함수명을 지을때는 clickEventHandler라고 짓는 걸 추천.
  • 좋은 코드를 위해 기억해야할 것은 일관성을 유지하고, 중복을 없애는 것❗️❗️❗️
    만약에 메소드 두 개가 비슷한 역할을 한다면, 중복을 없애고 싶은 생각이 들 것.
    대부분의 리팩토링은 중복을 없애는 것에서 시작된다.
    다른 부분만 변수에 담아서 parameter로 전달하는 것도 방법.
    ‘일관성’을 잘 지킨 코드가 좋은 코드!! 중요!!!!⭐️⭐️⭐️
    비슷한 역할을 하는 함수라면 똑같은 형태로 짜는 것이 좋음! 그래야 가독성이 좋다.
  • 해체할당(object destructuring) 문법을 쓰면 아주 유용함.
    #default parameter, destructuring, rest parameter 등등...
    ES6 문법들 공부해서 활용하기
  • Template literal(``)로 string을 만들어서 추가하면 DOM조작 명령어 (createElement, appendChild 등등)를 쓰지 않아도 됨.
    어떤 요소가 추가되는지 잘 보임. ( 반드시 해볼것!!!)
  • 자주쓰는 부분은 _(언더바)같은 이름으로 util을 하나 만들어서 재사용.

    실제로 언더스코어라는 라이브러리 같은 것들도 있다.
  • alert는 가급적 안쓰는 것이 좋다. 요즘 추세는 잘 쓰지 않는 것. 대신 숨겨져 있던 메세지가 보여지는 방식(display: none)을 사용할 수 있다.
  • <개발자 구직 관련 tip>
    원티드 사이트 애용하기
    적어도 두 달에 한번은 이력서를 써보면서 내 이력에서 추가된 것들은 뭐가 있는지 체크하기
    3년차를 찾는다고 해서 꼭 3년차여야지만 지원하는 게 아니다. 3년차 정도의 실력을 요구한다는 뜻.
    FE라면 React는 공부해야한다. TypeScript는 JavaScript는 잘 다룬다면 일주일 정도 잡고 공부하면 비교적 쉽게 배울 수 있다.
    포트폴리오는 코드가 필요하다. 소스코드❗️ 데모가 필요한 게 아님. 그래서 github을 잘 관리해야 한다.
    CS지식(데이터베이스, 네트워크, 자료구조) 꾸준히 늘려갈 것.
    우리가 공부해야하는 포인트는 HTML과 CSS를 잘 이해하되, 무엇보다 JavaScript를 잘 다루는 것이 중요.
    중요도 순 : JavaScript > HTML & CSS
    개발환경은 복잡하고 논리적이지는 않지만 어렵지는 않다. 공부하면 된다.
    유틸을 만드는 것이 라이브러리를 만드는 시작! 이걸 차곡차곡 쌓아가면 범용 유틸리티를 만들 수 있음.
    애자일 스크럼 이란?? 협력과 피드백
  • 커밋 로그(commit log)는 컨벤션을 따라 개선하기.
    feature: 새로운 기능 추가
    fix: 버그 수정
    Add
    Delete
    등등..
    구체적으로 설명을 쓰는 것도 가능하다. 찾아볼 것.
  • 반복되는(DOM cache)부분들은 변수로 담기.
  • 네이버의 대표적인 오픈소스 : egjs
    nhn이 고도화가 잘 되어 있음 : nhn toast ui도 참고.

To-do List 💪

<웹to-do 과제 2차 리팩토링>

  • 중복되는 부분은 유틸로 만들어보기
  • alert대신 display속성 사용해서 메세지 띄우기
  • 함수 breakdown: 더 작은 함수 단위로 쪼개기
  • 기능/역할이 다른 함수들은 또 다른 Class로 만들기

<공부가 필요한 주제들>

  • CSS: #float, #position, #box model (중요도 ⭐️⭐️⭐️)
  • 플러스 알파로 #grid, #flex
  • #default parameter, #destructuring, #rest parameter 등 자주쓰는 ES6문법 익히기
  • git Commit 컨벤션 찾아보기. log로 구체적인 설명도 적어볼 것!
  • 조금씩 CS 관련 공부(데이터베이스, 네트워크, 자료구조) 이어가기
  • 알고리즘 못푼 것들은 시간날 때 한번씩 다시 풀어보기
  • React 미리 배워두기
  • #이벤트전파, #캡쳐링, #버블링 델리게이션 공부하기

    이벤트 위임(Delegation):
    상위 요소에서 하위 요소의 이벤트들을 제어하는 방식으로, 요소마다 이벤트 핸들러를 할당하지 않고, 요소의 공통 조상에 이벤트를 할당해 여러 요소를 한꺼번에 다룬다. 비슷한 방식으로 여러 요소를 다뤄야 할 때 사용된다.
    어떤 프레임워크를 쓰느냐와는 관계없이 기본적인 브라우저의 이벤트 감지 방식!
    공통 조상에 할당한 핸들러에서 event.target을 이용하면 실제로 정확히 어디에서 이벤트가 발생했는지 알 수 있다.


    이벤트 버블링(Event Bubbling):
    이벤트 발생 시 해당 이벤트가 하위 요소 ➡️ 최상위 요소까지 전파되는 과정.
    하위 요소 중 하나를 클릭하면 순차적으로 최상위에 있는 화면 요소까지 이벤트들이 실행된다.
    ex. li태그로 추가 되어 있는 모든 input박스에 이벤트 리스너를 각각 추가하는 대신 상위 요소인 ul태그에 이벤트 리스너를 달면 하위에서 발생한 클릭 이벤트를 감지한다.

    <주의>
    각 태그마다 이벤트가 등록되어 있을 때만 상위요소로 전달이 일어남.

    이벤트 캡쳐(Event Capture):
    이벤트 발생 시 최상위 요소 ➡️ 해당 하위 요소를 찾아 내려가면서 이벤트가 전파되는 과정.
    이벤트 버블링과는 반대 방향으로 진행된다.
    addEventListener()를 사용하면서 옵션 객체에 capture:true를 설정해주면, 해당 이벤트를 감지하게 위해 이벤트 버블링과는 반대 방향으로 탐색한다.

    //ex.
     divs.forEach(function(div) {
     	div.addEventListener('click', logEvent, {
     		capture: true  📌📌📌
     	});
     });

    <주의>
    마찬가지로 각 태그마다 이벤트가 등록되어 있어야 한다.

    event.stopPropagation():
    이벤트가 전파되는 것을 막고싶다면 stopPropagation()을 사용하기.
    이벤트 버블링의 경우에는 클릭한 요소의 이벤트만 발생시키고 상위 요소로 이벤트를 전달하는 것을 방해한다. 그리고 이벤트 캡쳐의 경우에는 클릭한 요소의 최상위 요소의 이벤트만 동작시킨다.
    (이 외에도 preventDefault()return false를 사용할 수도 있다.)


Reference 📚

https://joshua1988.github.io/web-development/javascript/event-propagation-delegation/
https://ko.javascript.info/event-delegation
https://programmingsummaries.tistory.com/313
https://namu.wiki/w/%EC%96%B8%EB%8D%94%EC%8A%A4%EC%BD%94%EC%96%B4

profile
프린이의 코묻은 코드가 쌓이는 공간

0개의 댓글