Programmers JavascriptStudy Review

프로그래머스 자바스크립트 스터디에서 배운 것들과 정보들을 정리하고자 한다.







시작 전 참고자료





책 추천

  • 더글라스 크락포드의 자바스크립트 핵심가이드 - 더글라스 크락포드
  • 자바스크립트는 왜 그 모양일까? - 더글라스 크락포드
  • 자바스크립트 성능 최적화 - 니콜라스 자카스
  • 모던 자바스크립트 - 니콜라스 자카스 (es6문법 이해하는데 좋음)
  • 읽기 좋은 자바스크립트 코딩 기법 - 니콜라스 자카스
  • you don't know js - 중급자에게 추천





코드관련

  1. EOL (End of line)

    image

    • GitHub에서 이런 표시를 볼 수 있을 것이다.

      new line으로 끝나지 않은 행은 실제 행으로 간주되지 않을수도 있다. 항상 맨 아래에 비어있는 행을 추가하여 파일이 끝났음을 알려주어야 한다. POSIX명세에 이렇게 써있다.

      3.206 Line
      A sequence of zero or more non- <newline> characters plus a terminating <newline> character.

      prettier를 통해 저장시 자동으로 이 행이 추가되게 설정할 수 있다.

      {
        "endOfLine": "auto",
      }



  1. 단축평가, truthy, falsy 의 위험성

    if(!data) return;
    • js는 타입이 없어서 이런식으로 에러를 던지면 의도치 않은 동작이 발생할 수 있음.
    • null 체크는 lodash의 isNil을 참고



  1. 변수명
    • 줄임말을 사용하지 말자 Nm은 Name인지 Nanometer 인지 New Mexico인지 쓰는사람 말고는 모른다
    • 누구나 보고 최대한 이해하기 쉽게 설명적으로 작성하기
    • Javascript Naming Convention



  1. 비동기 처리
  • 저수준에서 발생시키고 고수준에서 처리 callee에서 발생, caller에서 처리

    • 예시코드

      // api.js
      const request = async () => {
        const response = await fetch('FAKE_URL');
        if (!response.ok) {
          throw new Error(response);
        }
        return response.json();
      };
      
      // index.js
      const HTTP_STATUS_CODE = {
        OK: 200,
        BAD_REQUEST: 400,
        NOT_FOUND: 404,
        SERVER_ERROR: 500,
      };
      
      const fetchData = async () => {
        try {
          const someData = await request();
        } catch (e) {
          switch (e.status) {
            case HTTP_STATUS_CODE.BAD_REQUEST:
              console.error('잘못된 요청이');
              break;
            case HTTP_STATUS_CODE.NOT_FOUND:
              console.error('찾는 데이터가 없음');
              break;
            case HTTP_STATUS_CODE.SERVER_ERROR:
              console.error('서버 에러');
              break;
            default:
              console.error(`에러: ${e}`);
          }
        }
      };
  • 비동기함수와 일반함수, 비동기 함수의 callback 시각화



  1. 시멘틱 태그, HTML의 중요성
  • 크롤러가 우리가 만든 사이트를 크롤링 해갈 때 HTML 코드만으로 그 의미를 인지하기 때문에 Semantic요소를 해석한다.

  • 웹은 누구나 이용 가능해야 한다.

  • 시멘틱 웹이란?

    • HTML의 시멘틱 태그에 대한 글, 시멘틱 웹이 왜 필요한지, 태그의 구조 등
  • facebook 에 공유하는 문서 최적화

    • 데스크톱, 모바일 웹, 모바일 앱 등 공유된 위치와 관계없이 Facebook에 공유하는 웹 호스팅된 콘텐츠를 최적화하는 방법
    • 시멘틱 태그가 중요한 이유
  • 구글검색 최적화

    • 구글 크롤러에 웹페이지 최적화 시키는 방법
    • 시멘틱 태그가 중요한 이유




인사이트




커뮤니티

  • 프로그라피 : 프로그래머와 디자이너의 모임, 팀별 프로젝트로 서비스 기획 및 배포
  • https://dnd.ac/ : 개발자와 디자이너가 함께 프로젝트 진행
  • DDD : 개발자, 디자이너가 함께 프로젝트 진행
  • 그 이외의 정보




사전퀴즈

  • 1번 문제 - new

    function Cat(name, age) {
      this.name = name;
      this.age = age;
    }
    const tabby1 = Cat('nana', 5);
    console.log(tabby1.name); //출력되는 값은?

    🔑 오류가 발생한다.

    apply, call, bind 등으로 this에 대해 주입한 상황이 아니고 new 키워드없이 실행한 함수 내 this는 전역 객체(window)를 바라보기 때문에 에러가 발생

    new를 붙이지 않았을 때 에러처리 필요 -> new.target으로 확인 가능!


  • 2번 문제 - 즉시실행함수

    (function (name) {
      console.log(`hello ${name}`);
    })('roto');

    🔑 hello roto가 출력된다.

    즉시실행함수 (IIFE, Immediately Invoked Function Expression) 이 함수를 정의함과 동시에 실행되기 때문에

    즉시실행함수 사용 이유 : 전역공간을 더럽히지 않고 코드를 모듈러 하려고 썼던 기법, 최근에는 const 나 let, 웹팩이나 모듈화되면서 그 역할들을 걔들이 해주고 있음


  • 3번 문제 - 함수의 스코프

    var idiots = {
      name: 'idiots',
      genre: 'punk rock',
      members: {
        roto: {
          memberName: 'roto',
          play: function () {
            console.log(`band ${this.name} ${this.memberName} play start`);
          },
        },
      },
    };
    
    idiots.members.roto.play();

    🔑 band undefined roto play start출력

    play 함수 안에는 name이 없기 때문

    해결하려면 console.log(`band ${idiots.name} ${this.memberName} play start.`)


  • 4번 문제 - 해당 코드를 실행하면 에러가 나는데, 의도대로 실행하는 방법을 아는대로 설명

    function RockBand(members) {
      this.members = members;
      this.perform = function () {
        setTimeout(function () {
          this.members.forEach(function (member) {
            member.perform();
          });
        }, 1000);
      };
    }
    
    var theOralcigarettes = new RockBand([
      {
        name: 'takuya',
        perform: function () {
          console.log(' a e u i a e u i');
        },
      },
    ]);

    🔑 theOralcigarettes.perform()을 실행하는 함수가 빠짐

    🔑 setTimeout으로 인해 this는 RockBand의 this가 아님

    해결법 1. 클로저 이용

    function RockBand(members) {
      var that = this; //context 밖에 있는 변수에 접근하기 위한 것
      this.members = members;
      this.perform = function () {
        setTimeout(function () {
          that.members.forEach(function (member) {
            member.perform();
          });
        }, 1000);
      };
    }

    해결법 2. bind이용

    function RockBand(members) {
      var that = this;
      this.members = members;
      this.perform = function () {
        setTimeout(
          function () {
            this.members.forEach(function (member) {
              member.perform();
            });
          }.bind(this),
          1000,
        );
      };
    }

  • 5번 문제 - 해당 코드를 실행하면 숫자가 순차적으로 출력되지 않고 5만 출력된다. 왜 그런 현상이 발생하는지, 어떻게 수정하면 좋을지 서술

    const numbers = [1, 2, 3, 4, 5];
    for (var i = 0; i < nummbers.length; i++) {
      setTimeout(function () {
        console.log(`number index ${i}`);
      }, 3000);
    }

    setTimeout이 실행되는 시점에는 루프가 이미 끝나있어서 i=5

    실제로 for문 안의 varglobal영역임

    🔑 var i = 0let i = 0으로 쓰는 것으로 해결

    🔑 setTimeout을 IIFE로 감싸고 파라메터로 i를 넘기는 것으로 해결

    const numbers = [1, 2, 3, 4, 5];
    for (var i = 0; i < numbers.length; i++) {
      (function (count) {
        setTimeout(function () {
          console.log(`number index ${count}`);
        }, 1000);
      })(i);
    }

  • 7번 문제 - var, let, const차이

    🔑

    var : function level scope, 호이스팅 현상, 재할당가능

    let : block level scope, 재할당 가능

    const: block level scope, 재할당 불가능, 그러나 할당된 객체의 함수를 이용해 객체 변경 가능

    ex)

    const arr = [];
    arr = [1, 2]; //error
    
    arr.push(1); //가능