ziglog

    Search by

    우테코 5주차 기록

    March 6, 2021 • ☕️☕️☕️☕️ 21 min read

    우테코 5주차 기록


    페어 프로그래밍

    • 새 페어 심바와 매칭이 됐다. 아직 이전 미션의 후유증(?)이 가시지 않은 채로 바로 새 페어와 새 미션을 진행하는 게 걱정이 됐었다.
    • 이번주부터 등교를 시작해서 서로 얼굴 보고 얘기할 수 있게 돼서 그런 걸까? 순식간에 페어와 친해졌다!
    • 페어가 제안한 대로 20분씩 정확히 끊어서 페어 턴을 교체하기로 했다. 그리고 우리 모두 밤늦게까지 일하는 타입은 아니기 때문에 낮에 깨어있을 동안 열심히 하고 제출하기로 다짐했다.
    • 페어 턴 교체는 만나서 웃고 떠드느라 제대로 교체되지 못했는데, 다른 사람 코드 칠 동안 구경만 하는 것이 아니라 계속 생각나는 대로 공유하고 코드를 같이 작성하며 진정한 의미의 페어 프로그래밍을 진행했다.
    • 걱정했던 것보다 더 미션이 어려워서 😵 밤늦게까지 일하지 말자는 다짐은 하루만에 깨지고 말았다.
    • 오랜만에 사람들을 만나 미친 송아지마냥 🐄 이리저리 말 걸고 다니는 내게 한 번도 뭐라고 하지 않고, 정말 특이하고 웃기다며 같이 잘 놀아주기도 하고(?) 피곤해 보이면 잠깐 쉬고 오라고 말해주는 배려심 많은 페어다.
    • 로직을 생각하는 건 좋아하지만 타이핑은 조금 귀찮아하는 페어는 내게 타이핑을 시킬 때도 종종 있는데, 사실 생각하는 것보다 일단 모조리 타이핑을 시작해보는 타입인 나와는 합이 잘 맞는다고 생각한다!

    로수타 (+포수타, 2수타)

    • 로이드는 기술이사셨다! 오랜 개발 경력을 쌓아 높은 자리까지 올라가셨는데, 매일같이 회의하고 많은 결정을 내려야 하는 자리도 상당히 피곤할 것 같다. 그리고 포코와의 옥상타임에서 주워들은 바 상당한 내공의 소유자이심을 알 수가 있었다. 아마 우형 프론트 입사는 글렀나 보다 😭
    • 점점 괴상한 밸런스 게임이나, 로이드는 안드로이드만 쓰는지에 대한 질문 등 드립들이 난무하는 시간이었다. 갈수록 크루들이 편해지면서 똘끼와 드립을 마구 던지는 분위기가 아주 좋다 😎
    • 전날 새벽까지 일하고 로수타 시간에 너무 잠이 왔어서, 사실 로수타보다는 2수타(2기와의 수다 타임)와 포(코)수타가 기억이 남는다.

    몇 달 뿐이었지만 인턴을 2번 해본 경험에 비추어 봤을 때, 정말 회사 다니면 아무것도 못하게 된다는 말에는 동의한다. 당시 나는 아무것도 책임질게 없는 20대 초반 대학생이었지만, 정말 다른 공부는 아무것도 할 수가 없다. 그래서 지금 우테코에 있는 이 기간 동안 모든 시간을 투자해서, 미친 듯이 열심히 해보라는 2기 선배들과 포코의 조언도 이해한다. 그런데 나는 내가 맘 먹어야만 일을 시작하는 사람인 것도 너무 잘 알고, 지금도 남들 눈엔 열심히 하고 있어 보이겠지만 있는 힘껏 최선을 다하고 있지 않다는 것도 안다.

    자기 생에서 그 누구보다도 열심히 하던 시절을 한 순간 뽑으라면, 언제 물어봐도 나는 “고등학교 3년이었다”고 답할 것이다. 그래서 그때의 열정은 다시 오지 않을 것이라고 생각했다. 그때 이미 모든 걸 쏟아버려서, 다신 그렇게까지 쏟지는 못하겠다고. 그런데 최근 생각해보니, 다시 온 정신과 열정을 투자할 때가 ‘아직’ 오지 않은 것 같다.

    몸과 정신 건강을 다 잃은 적이 있었기에 아직 회복 중인 걸 수도 있고, 그냥 아직 시기가 아닐 수도 있다. 그렇지만 나는 나를 믿고, 이곳에서의 시간들이 결코 헛되지 않을 것이라고 생각한다. 그리고 아직 나는 20대 중반 젊은이니까 🤓


    테코톡

    그동안 프론트엔드 면접 때마다 가장 많이 공부했지만 가장 헷갈리는 개념 중 하나였던, 그러나 Javascript의 <근본>이라고 할 수 있는 prototype에 대한 테코톡을 진행했다. 지난번에 정리한 내용을 참고하면 좋을 것 같다. 😉 (왜 마크다운 링크로 안 걸리는지 모르겠다 😬)

    Ref https://zigsong.github.io/woowa/woowacourse-3/#prototype—mixin


    👨‍🏫 강의

    로또 미션 공통 피드백 - 3

    template의 중복 줄이기 지금 진행 중인 유튜브 미션에서 중복되는 template을 모아두고 쓰도록 코드를 설계했는데, 지금도 괜찮아 보이지만(?) 앞으로 있을 단계들에서 더욱 고민하여 중복된 긴 template을 처리하도록 해야겠다.

    let i for문 ❌ for 문은 index 변수, 조건, 카운팅 등 휴먼 에러가 날 가능성이 높다!

    Copy
    // index for loop 대신
    for (let i = 0; i < totalCount; i++) {
      lottos.push(new Lotto(totalCount.pop()));
    }
    
    // Array 메소드를 사용하자
    [...Array(totalCount)].map(() => lotto.push(new Lotto(totalCount.pop()));

    매직 넘버에 이름 붙이기 귀찮거나 해서 맨날 무시하다가 나중에 더 귀찮아지는 일이다 😵 유지보수를 위해 항상 신경쓰기

    만능 함수 쪼개기

    • 점점 미션에서 요구하는 기능들이 많아지면서 함수 하나의 바디가 나도 모르게 커지는 일들이 비일비재하다.
    • handler를 하나 만들고 그 안의 로직을 작은 단위의 함수로 나누는 방법도 있다.
    • 추상화와 단순추출을 구분하자!

    반전 불가능 네이밍 대신 검색하기

    • displayhide보다는, showhide의 네이밍이 적절하다.
    • 적절한 이름을 짓지 못하겠다면 jQuery 등 잘 짜여진 라이브러리를 참고하자

    사극에서 벗어나기

    • 최근의 네이밍 컨벤션을 사용하자
    • 헷갈리는 부분들은 react github, 기타 오픈소스 등에서 확인할 수 있다

    웹의 동작

    웹 서버와 클라이언트

    • client가 요청(request)을 보내면 server가 응답(response)하는 구조로 되어 있다.
    • 웹에서 다양한 콘텐츠를 불특정 다수의 사람에게 공개하려면 콘텐츠를 적절히 정리하고 관리해야 하는데, 그런데 이 콘텐츠들이 여러 곳에 분산돼 있으면 문제가 발생한다. 웹에 존재하는 대부분의 콘텐츠는 업데이트가 이루어지는데, 콘텐츠가 여러곳에 분산돼 있으면 어디에 저장되어있는지 파악하고 동시에 갱신하는 것이 매우 어렵고 비용이 많이 드는 작업이다. 따라서 웹 서버와 같이 컴퓨터 하나에 정보를 모아 두어야 관리하기가 쉬워진다.
    • client(유저)가 콘텐츠를 찾을 수 있도록 인터넷 상의 콘텐츠를 고유하게 지정해 놓은 구조가 URL(Uniform Resource Locator)다. 웹 브라우저에 특정 사이트로 접속하기 위해 주소창에 입력하는 문자열을 가리킨다.

    HTTP

    • 웹 서버와 웹 클라이언트가 통신하기 위해 어떻게 정보를 주고받을지에 대한 약속을 통신 프로토콜(communication protocol)이라고 한다.
    • 웹의 창시자 버너스 리 박사는 HTML 전송에 적합한 프로토콜을 고안하였고, 그것이 널리 쓰이는 HTTP 프로토콜이 되었다.
    • URL(Uniform Resource Location)은 URI의 하위 개념이지만, 현재 혼용해서 사용하고 있다.

    https://zigsong.github.io/woowa/woowacourse-5/

    위와 같은 URL에서 https는 ‘스킴’, zigsong.github.io는 ‘호스트명’, woowa/woowacourse-5/는 ‘경로명’으로 구분한다. 스킴은 리소스를 획득하기 위한 방법(HTTP 프로토콜), 호스트는 리소스가 존재하는 호스트(컴퓨터)의 이름, 경로는 호스트명에서 지정된 컴퓨터상의 리소스 위치를 나타낸다.

    HTTP Request는 다음 부분들로 구성된다. 01

    HTTP Response는 다음 부분들로 구성된다. 02

    아래는 자주 사용되는 HTTP method의 종류다. 03

    Ref https://developer.mozilla.org/ko/docs/Learn/Getting_started_with_the_web/How_the_Web_works


    AJAX & JSON

    AJAX(Asynchronous JavaScript and XML) AJAX(또는 XMLHttpRequest)는 비동기 방식으로 데이터를 주고받기 위해 개발된 자바스크립트 기술이다. AJAX는 HTML, XML, JSON 등 다양한 데이터를 주고받을 수 있으며, 최근에는 주로 JSON 데이터 형태로 자리잡았다.

    AJAX 통신을 위해서 자바스크립트가 사용하는 XMLHttpRequest 객체는 자바스크립트의 내장 객체로 비동기 통신 구현을 위한 객체이며, 이 객체는 서버로 요청을 보내고 요청받은 결과를 비동기로 처리한다.

    따라서 요청을 보낸 후 사용자는 UI 화면과 상호작용을 하거나 다른 AJAX 요청을 추가로 보낼 수 있다. 서버에서 응답이 오면 AJAX 요청을 보낼 때 등록한 콜백 함수를 통해 결과 데이터를 처리한다. AJAX의 ‘비동기성’을 이용하여 페이지 전체를 리프레쉬하지 않고서도 DOM에서 수정된 부분만을 업데이트할 수 있다.

    JSON(JavaScript Object Notation)

    AJAX로 받아오는 대부분의 데이터는 JSON 포맷이다. JSON으로 전송하는 데이터의 양이 HTML보다 훨씬 적기 때문에 느린 인터넷 환경, 특히 모바일 환경에서 더 빠른 페이지 로딩과 페이지 갱신을 보장할 수 있다. 따라서 동적 웹페이지를 생성하는 데 있어 JSON을 사용한다.

    웹에서 오고 가는 데이터의 대부분이 JSON으로 표현이 가능하기 때문에 사실상 JSON 포맷이 표준으로 정착해 있다. AJAX 응답으로 받은 JSON 데이터는 단순 문자열이기 때문에 데이터 변환을 해야 한다. XMLHttpRequest의 응답 객체에는responseText 속성이 있고, 이 속성에 응답으로 받은 JSON 텍스트 데이터가 있다. 이 데이터를 JSON 객체로 변환해서 사용한다.

    자바스크립트에는 전역 객체로 JSON 객체가 있으며, JSON 문자열을 객체로 변환해주는 메서드가 제공된다.

    Copy
    const json = JSON.parse(xhr.responseText);

    Ref


    RESTful API

    REST(Representational State Transfer)는 자원을 이름(자원의 표현)으로 구분하여 해당 자원의 상태(정보)를 주고 받는 모든 것을 의미한다.

    REST는 HTTP URI(Uniform Resource Identifier)를 통해 자원(Resource)을 명시하고, HTTP Method(POST, GET, PUT, DELETE)를 통해 해당 자원에 대한 CRUD Operation을 적용하는 것을 의미한다.

    REST는 웹의 기존 기술과 HTTP 프로토콜을 그대로 활용하여 웹의 장점을 최대한 활용할 수 있는 아키텍처 스타일이다.

    REST의 특징은 다음과 같다.

    • Server-Client(서버-클라이언트 구조)
    • Stateless(무상태)
    • Cacheable(캐시 처리 기능)
    • Layered System(계층화)
    • Code-On-Demand(Optional)
    • Uniform Interface(일관성)

    REST API란 REST 기반으로 서비스 API를 구현한 것으로, 최근 OpenAPI(누구나 사용할 수 있도록 공개된 API: 구글 맵, 공공 데이터 등), 마이크로 서비스(하나의 큰 애플리케이션을 여러 개의 작은 애플리케이션으로 쪼개어 변경과 조합이 가능하도록 만든 아키텍처) 등을 제공하는 업체 대부분은 REST API를 제공한다.

    Ref


    Promise

    비동기적인 함수 실행의 처리를 위해 등장한 callback, 그러나 비동기 함수에서 비동기 함수를 호출하는 일이 반복되어 발생하는 callback 지옥을 벗어나기 위해 Promise의 개념이 등장하였다.

    Copy
    callback1(function (value1) {
      callback2(value1, function (value2) {
        callback3(value2, function (value3) {
          callback4(value3, function (value4) {
            // ...
          });
        });
      });
    });

    Promise는 콜백 함수를 인자로 받는 대신에, 성공과 실패에 대응하는 메서드를 제공한다. 그래서 콜백 함수를 중첩하지 않고, 여러 개의 비동기 동작을 연결할 수 있다.

    Promise는 비동기 작업이 성공(success)하거나 충족(fulfilled)된 경우 .then() 메서드를, 실패(fail)하는 경우에는 .catch() 메서드를 호출한다. 이때 두 메서드에 전달되는 함수에는 비동기 작업의 결과인 응답만이 인수로 전달된다.

    Promise는 두 개의 인자 resolve()reject()를 전달 받는다. 코드가 정상적으로 작동하여 resolve()가 반환되면 then()에 전달된 함수가 실행되고, 실패한 경우 reject()가 반환되어 catch() 함수를 실행한다.

    Copy
    new Promise(function (resolve, reject) {
      // ...
    })
      .then(resolve())
      .catch(reject());

    주로 사용하는 Promise 도구인 fetch는 아래와 같이 사용한다.

    Copy
    fetch(url)
      .then((res) => {
        return res.json();
      })
      .then((post) => {
        console.log(post.title);
      });

    😮 이때 주의할 점은 json()메서드도 Promise를 반환하기 때문에 then() 메서드를 추가해야 한다. 추가한 then() 메서드에서 콜백에서 파싱된 데이터를 처리할 수 있다.

    Content-type과 같은 header를 넣어 요청을 보낼 수 있다.

    Copy
    const option = {
      method: "POST",
      headers: {
        "Content-Type": "application/json",
      },
      body: JSON.stringify(newPost),
    };
    
    fetch(url, option)
      .then((res) => {
        if (!res.ok) {
          throw new Error(res.status);
        }
        return res.json();
      })
      .then((post) => {
        console.log(post.title);
      })
      .catch((error) => {
        console.log(error);
      });

    async-await을 사용하여 Promise를 더욱 편리하게 사용할 수 있다.

    async 키워드를 이용해서 선언한 함수는 비동기 데이터를 사용한다는 것을 의미한다. 비동기 함수의 내부에서 await 키워드를 사용하면 값이 반환될 때까지 함수의 실행을 중지시킨다. await을 호출하는 함수는 반드시 async 함수 안에서 실행되어야 한다

    Copy
    async function getUser() {
      const zig = await getTargetUser();
    
      return zig;
    }

    Ref https://joshua1988.github.io/web-development/javascript/promise-for-beginners/


    👀 PR 구경하기

    는 말도 안 되지만 한 개도 하지 못했다… 주말에 몰아서 해도 됐었지만 사람다운 삶을 살기 위해 이번 주말도 잠시 숨을 돌리기로…


    📚 배우기

    90년생 HTML

    • 90년도부터 시작한 html, 고향은 스위스 CERN 연구소
    • 웹의 등장
    • 클라이언트와 서버로 분리한 이유?
      • 데이터의 일관성 유지
      • 웹 서버로 만들어서 인터넷으로 연결하여 사용
    • 원하는 리소스를 찾는 방법
      • 단순히 페이지에서 주소를 치는 것 뿐 아니라, 인터넷 상에 존재하는 콘텐츠의 고유한 값
      • 자원 요청에 대한 구체적인 부분들
    • 데이터를 주고 받는 방법의 진화
      • AJAX
      • RESTful API

    프로그래밍은 상상이다

    소프트스킬

    • 협력을 통한 추상화
    • 톱니바퀴 실험
      • 규칙을 정하기 위해 추상적 개념을 도입하게 됨
      • 어느 쪽이 좌측/우측인지 서로 다른 시각을 공유
    • 다른 시각을 가진 두 사람이 협력하기

    면접 스킬

    • 그림을 그리며 추상화
    • 상대의 질문에 리액션
    • 상대방과 질문 주고 받으며 상자 밖에서 생각하기
    • “that’s a good question!”

    function apply, call 지난 테코톡 때 this binding을 다루며 나온 주제인데, 막상 쓰려니까 겁이 나기도 하고 😬 적확한 사용이 어려웠다. 코치님의 도움을 받아 페어와의 미션에 적용시켜 보았다.

    미션에 작성한 코드는 아래와 같다.

    Copy
    // view
    this.modalVideos.addEventListener(
      "scroll",
      // 6. 실행되는 순간 이곳에는 setTimeout 함수가 남는다.
      throttle(function (event) {
        const { scrollTop, scrollHeight, offsetHeight } = event.target;
    
        if (scrollTop === scrollHeight - offsetHeight) {
          // 7. throttle 함수 안의 callback에서 바인딩해준 this를 가지고 있기 때문에(5번) this는 view를 가리킨다.
          this.emit("scrollResult", this.searchKeyword);
        }
        // 1. 여기서 미리 명시적 binding을 해준다.
      }, VALUE.THROTTLE_TIME).bind(this)
    );
    
    // throttle.js
    export default function throttle(callback, delay) {
      // 2. 이 함수 내부에서 this는 view에서 binding해 준 this이다. (view를 가리킴)
      let ticking;
    
      // 3. 함수 내부에서 함수를 리턴하여, view에서 scroll 발생 시 listener 부분에는 아래 setTimeout 함수만 남게 된다.
      return function () {
        // 4. 클로저 함수는 위에 선언된 ticking을 참조한다. (기억하고 있다.)
        if (ticking) return;
    
        ticking = setTimeout(() => {
          ticking = null;
          // 5. callback 함수에 this(여기서는 view를 가리킴)를 바인딩해준다.
          callback.apply(this, arguments);
        }, delay);
      };
    }

    view에서 throttle 함수를 사용하고 싶은데, 이때 view에서 event target으로 받아오는 scroll data들을 넘겨줘야 했다.

    throttle 함수는 함수를 리턴하는 클로저 함수다. 따라서 view에서 scroll event가 발생할 때 listener 부분에는 throttle 함수가 리턴하는 setTimeout 함수만 남게 된다. this는 현재 객체(호출하는 객체)를 참조하기 때문에 view에서 호출하는 throttle 함수에서 bind(this)를 해준 후 throttle 함수 내부에서 callback에 apply를 해줌으로써 this binding이 이루어진다. view를 가리키는 this가 view의 bind → throttle의 apply를 한 바퀴 돌아 다시 view에서 사용되고 있다.

    callapply는 명시적 binding으로, this를 강제로 바인딩시켜준다.

    아래는 주말 밤 코치님의 특훈쓰…

    Copy
    const zig = {
      name: "zig",
    };
    
    function sing(play) {
      console.log(`${this.name} ${play}`);
    }
    
    // 1. call 사용
    console.log(sing.call(zig, "is singing rollin"));
    // output: zig is singing rollin
    
    // 2. bind 사용
    const zigSing = sing.bind(zig); // sing 함수에 zig가 바인딩된다.
    zigSing("is dancing"); // 위에서 binding되는 순간에 zigSing은 zig를 기억하고 있다.
    // output: zig is dancing

    call의 this에 zig를 넣어주면 sing 메소드의 this는 zig에 바인딩된다. 또 인자로 ‘is singing rollin’을 넘겨줌으로써 결과적으로 ‘zig is singing rollin’을 출력하게 된다.

    🤓 callapply는 거의 비슷하지만, call은 인수 목록을, apply는 인수 배열 하나를 받는다는 점이 차이점이다. mdn에서 callapply의 유용한 쓰임들을 확인할 수 있다.

    Ref

    closure currying 함수를 반환하는 자바스크립트 closure 특성을 이용하여 currying이라는 패턴을 사용한다. currying은 함수를 즉시 평가하고 반환하는 것을 가리킨다.

    Copy
    let greeting = function (a) {
      return function (b) {
        console.log(a + " " + b);
      };
    };
    
    let hello = greeting("Hello");
    let morning = greeting("Good morning");
    
    hello("Zig"); // Hello Zig
    hello("Jay"); // Hello Jay
    morning("Zig"); // Good morning Zig
    morning("Jay"); // Good morning Jay

    greeting으로부터 생성된 hellomorning 함수는 콘솔에 인사말을 찍는 함수를 받는다. 그리고 각각은 인사 받을 사람의 이름을 인자(b)로 받고 있다.

    greeting 함수에서 리턴되는 내부 함수는 greeting이 받는 파라미터(a) 이후에 인자(b)를 받아서 실행할 수도 있다.

    Copy
    greeting("Hello There")("Zig Song");
    // Hello There Zig Song

    ES6의 arrow function을 이용하여 아래와 같이 쓸 수도 있다고 한다.

    Copy
    let greeting = (a) => (b) => a + " " + b;
    
    greeting("Hello There")("Zig Song");
    // Hello There Zig Song

    새로운 개념이 아닌, 자바스크립트의 closure 패턴을 활용한 함수의 사용이라고 보면 되겠다. 수학적으로 접근하면 이런 느낌 🙄

    Copy
    f(a, b, c)> f(a) => g(b) => h(c).

    Ref

    observer pattern

    observer pattern은 RxJS나 swift를 할 때 조금씩 사용했던 패턴이다. 항상 지켜봐줘야 하는 state를 observable object로 만들고, 비즈니스 로직을 담당하는 여러 controller에서 해당 state를 update시켜주거나 subscribe를 통해 상태의 변화를 항상 추적한다. 즉 controller가 state의 상태를 항상 관찰하는 observer가 되는 것이다.

    이번 유튜브 미션은 기능을 수행하는 곳이 다양해진 만큼 controller의 분리와 상태의 관리가 필요해졌다. 개념 자체는 어렵지 않은데 모든 것을 처음부터 vanilla javascript로 구현해야 하는게 어렵다 😱 그래두 다른 갓갓 크루들의 코드들을 보며 조금씩 바꿔나가고 있다. 😎

    이때 Subject라는 이름으로 명명한 하나의 모듈에 상태 관리가 필요한 대상들을 넣어 대상에 update가 발생할 때마다 연결된 모든 observer에 알려주게끔(notify) 만들 수 있다.

    Copy
    class Subject {
      constructor() {
        this.observers = [];
      }
    
      registerObserver(observer) {
        this.observers.push(observer);
      }
    
      unregisterObserver(observer) {
        this.observers = this.observers.filter(
          (registeredObserver) => registeredObserver !== observer
        );
      }
    
      notifyObservers(data) {
        // 함수로 넣었을 때
        // this.observers.forEach(observer => observer(data));
        this.observers.forEach((observer) => observer.notify(data));
      }
    }
    
    const subject$ = new Subject();

    사실은 javascript의 addEventListener도 observer pattern을 적용시킨 것이라고 볼 수 있다. 이벤트(Subject)를 구독하여(addEventListenr) 변화를 감지할 때마다 옵저버(callback)에게 알려서 실행하는 것이다.

    Ref

    netlify 배포 & API key 등록

    API key를 담은 파일을 올리면 github page로 데모 사이트를 빌드할 수가 없어서, 처음으로 netlify를 통해 배포를 시도했다.

    netlify를 이용한 정적 페이지는 어렵지 않았다. 다만 빌드 시 echo 명령어를 통해 file에 API key를 입력해주고 있어서, 배포된 페이지의 source tab에 들어가 보면 여전히 key가 노출되어 있다. 😂 프론트엔드 구현만으로는 key를 완벽하게 숨길 수 없다. 미션 기능 구현을 마무리하고 다른 크루가 알려준 방식대로 API key를 받는 서버를 따로 만들어야할 것이다.

    Ref https://www.youtube.com/watch?v=2J3xbMkH2K4

    javascript의 함수 vs 메소드

    등교한 어느날 코치님이 물어보셨는데 아무도 똑바로 대답하지 못했다 😵

    🤔 함수는 함수고, 메소드는 클래스에 종속되어 있는 함수 아냐?

    틀린 말은 아닌 것 같지만, 제대로 이해를 해보자!

    아래는 고개를 끄덕이게 하는 설명들이다.

    • 함수가 메소드를 아우르는 포괄적인 용어이다.
    • 함수는 객체로부터 독립적이며, 메소드는 객체에 종속적이다.

    그러면 내 생각이 맞는 것 아닌가? 할 수 있지만, 메소드와 함수의 차이를 보다 분명하게 확인해보자.

    • 메소드는 호출된 객체에 암시적으로 전달된다.
    • 메소드는 클래스 안에 있는 data를 조작할 수 있다.

    You don’t know JS의 카일심슨이 설명하는 내용은 조금 추상적이지만 흥미롭다.

    Copy
    function foo() {
      console.log("foo");
    
    var someFoo = foo; // 'foo'에 대한 변수 레퍼런스
    var myObject = {
        someFoo: foo
    };
    
    foo; // function foo() {...}
    someFoo; // function foo() {...}
    myObject.someFoo; // function foo() {...}

    someFoomyObject.someFoo 모두 같은 함수를 가리키는 개별 레퍼런스일뿐, 뭔가 특별한 다른 객체가 ‘소유한’ 함수라는 의미는 아니라는 것이다.

    결론적으로 ‘객체(클래스)로부터 독립적인가 아닌가’가 함수와 메소드를 나누는 기준이다. 원래 생각과 무슨 차이가 있는지 아직도 잘 모르겠긴 하지만 🙄 다음에 사람들과 토론해봐야겠다.

    Ref https://sustainable-dev.tistory.com/33


    기타

    srcdoc

    <iframe> 태그의 srcdoc 속성은 <iframe> 요소에 보일 웹 페이지의 HTML 코드를 명시한다. src 속성보다 우선시되는 속성값이기 때문에, 브라우저가 srcdoc 속성을 지원하면 <iframe> 요소의 src 속성값은 srcdoc 속성값으로 재정의된다.

    하지만 srcdoc 속성이 명시되어 있지만 해당 브라우저가 srcdoc 속성을 지원하지 않으면, <iframe>은 src 속성에 명시된 파일을 보여준다.

    사용자에게 보다 빠르게 <iframe>을 보여주기 위해, 비동기적으로 불러온 영상의 링크를 아직 받아오지 않았을 때 srcdoc 속성에 영상의 썸네일을 먼저 로딩 후 해당 <iframe>을 클릭하면 비로소 src 속성의 링크가 뜨도록 만들 수 있다.

    Ref https://www.w3schools.com/tags/att_iframe_srcdoc.asp

    <button> default type

    <button> 태그의 default type은 submit이다. <button type="submit">을 굳이 넣어줄 필요는 없고, <input type="submit">만 잘 챙겨주면 되겠다.

    Intersection Observer API

    이미지나 컨텐츠의 지연 로딩, infinite scroll, 광고의 가시성 보고 등에 사용되는 API다. 감시하고자 하는 요소가 다른 요소(viewport)에 들어가거나 나갈 때 또는 요청한 부분만큼 두 요소의 교차부분이 변경될 때마다 실행될 콜백 함수를 등록할 수 있게 한다.

    Copy
    let options = {
      root: document.querySelector("#scrollArea"),
      rootMargin: "0px",
      threshold: 1.0,
    };
    
    let observer = new IntersectionObserver(callback, options);

    🤓 설정한 scroll 영역에서 관찰 대상이 되는 요소가 사용자의 화면에 지금 보이고 있는지 아닌지를 측정하여 infinite scroll 기능을 구현하는 데 사용할 수 있다.

    Ref

    target blank noopener

    아래와 같이 a 태그를 noopener 옵션 없이 사용했을 경우 연결 중인 페이지는 연결 페이지에 부분적으로 접근할 수 있다. 연결된 페이지의 콘솔에서 window.opener를 찍어서 확인할 수 있다. 이는 악의적인 조작이 가능하다는 것이다! 😱

    Copy
    <a href="https://www.zigsong.github.io" target="_blank">
      ziglog
    </a>

    이때 rel 속성으로 noopener를 넣어주면, 연결된 페이지에 window.opener 객체가 존재하지 않게 된다.

    Copy
    <a href="https://www.zigsong.github.io" target="_blank">
      ziglog
    </a>

    noopener와 유사한 기능으로 noreferrer가 있다. noreferrer는 새로 열린 웹사이트가 window.opener 객체를 조작하지 못하게 한다. 링크를 클릭할 때 참조자 정보를 숨겨, 클릭한 사용자가 어디서 왔는지 알 수 없게끔 만든다.

    noopenernoreferrer 두 가지를 모두 사용하는 것이 좋다고 한다! 😉

    Ref https://webruden.tistory.com/262

    모달 관련 UX

    한 리뷰어님께서

    모달이 open인 상태에서 document body 의 scroll을 lock 해주는 UX를 생각해보자

    고 하셨다. 역시 현업자는 다르다… 섬세한 프론트엔드 엔지니어…

    CSS grid

    😵 오랜 시간 elements 탭을 뜯어보게 만들었던 grid… 컨테이너에 display: grid를 적용한 후, flex와 마찬가지로 컨테이너에 먹이는 값, grid item 각각에 먹이는 값으로 나뉜다.

    내용이 방대하기 때문에 링크 참고 😉

    Ref

    BEM

    • BEM은 CSS 제작 방법론으로, 일종의 네이밍 컨벤션이다. html 요소들을 각각 Block, Element, Modifier 세 가지로 분류해 작명하는 방식이다. ‘목적’에 따라 네이밍하는 것이 특징이다.
    • Block - 독립적으로 존재하고 재사용 가능한 요소를 Block으로 명명한다.
      • 태그 값과 id 대신 클래스로 DOM을 선택한다.
      • 재사용을 위해 position, margin 등의 위치값을 지정하지 않는다.
      • 색상이나 크기 등을 묘사하는 이름은 지양하며, 구조적으로 의미 있는 이름로 작명한다.
    • Element - block 내부에 종속되어 실제 기능을 담당한다. 종속의 의미를 block-name__element-name로 나타낸다. 독립적으로 존재하지 않으며, block에 의존적이다. 따라서 block에서 떼내어 다른 곳에서 가져다 쓸 수 없다.
    • Modifier - block이나 element의 속성을 가리킨다. --__를 사용하여 표현한다.

    결론적으로 block-name--modifier-name, block-name__element-name--modifier-name의 형태로 작성할 수 있다.

    Copy
    .header__navigation--focused {
      color: red;
    }

    위와 같은 css 코드가 있을 때 header는 Block, navigation은 Element, focused는 Modifier가 된다. header는 어디에서나 가져다 쓸 수 있으며, navigationheader에 종속되어 있는 탭들이라고 할 수 있다. focusednavigation 중에서 조금 다르게 보여질 것이다. 따라서 해당 element의 속성값이다.

    Ref


    🤔 생각해보기

    그런 API로 괜찮은가 https://tv.naver.com/v/2292653


    😎 마무리

    처음으로 등교를 시작했다. 준비 시간, 이동 시간 합쳐서 하루 3시간은 까먹고 몸의 피로함은 배가 됐지만 너무너무 재밌고 행복하다! 같은 과제를 하고 비슷한 목표를 향해 함께 달려가며 고민하고 웃고 떠드는 과정들이 정말 즐겁다. 취업 안 하고 평생 이렇게만 살아도 좋을 만큼 재미있다 (하지만 돈 벌어야 하기에…😂)

    그래서 우테코 2기 선배가 내게 우테코를 추천했던 것보다도 더욱 많이 주변 사람들에게 우테코를 추천하고 싶다. 너무나도 다양한 배경에서, 다양한 이유로 웹개발을 시작하게 된 사람들이지만 그 열정만큼은 정말 눈이 부실 만큼 멋지다. 개발하며 사실 어휘력이 많이 떨어져서, 멋지다는 표현도 너무 부족할 만큼 멋진 크루들이다.

    불금에는 같이 불코딩하고 간단히 맥주도 한 잔 했다. 다들 친화력 갑 👍 매주 같이 술 한잔씩 했으면 좋겠다! 5인 제한이 어서 풀려서 조금 더 많은 크루들과 모여 짠하는 날이 빨리 왔으면 좋겠다.

    습득력은 빠를지 몰라도 사실 열정은 그렇게 크지 않았던 내게 귀감이 되어주는 소중한 크루들, 그리고 항상 격려해주고 조언을 아끼지 않는 코치님들이 있기 때문에 조금 벅차고 피곤하지만 계속해서 달려나갈 힘이 생기는 것 같다. 때로는 슬럼프도, 번아웃도 오겠지만 끝까지 화이팅할 수 있기를 😎–


    Relative Posts:

    우테코 Lv1 Lotto PR로그

    March 8, 2021

    우테코 Lv1 lotto 학습로그

    March 2, 2021

    zigsong

    지그의 개발 블로그

    RotateLinkImg-iconRotateLinkImg-iconRotateLinkImg-icon