오늘의 삽질

  • 오늘은 강의 시청 및 과제 제출이 주를 이뤄 실습간 큰 문제가 없었다.

개선점 분석

  • 위와 동일하게 능동적인 작업이 없었다.

지식창고

[JS 문법 종합반] 강의

콜백함수(Callback function)

  • ‘다른 코드’의 인자로 넘겨주는 함수로, 다른 코드가 끝난 뒤에 실행되는 함수를 말한다! => 호출하는 ‘다른 코드’가 콜백함수의 제어권을 가지고 있음

  • 콜백함수를 호출한 ‘다른 코드’ 만이 콜백함수의 매개변수(인자)를 제어할 권리를 가짐

  • 콜백함수의 this는 기본적으로 ‘함수’ 이기 때문에 전역 객체가 반환되지만, 예외적으로 호출하는 ‘다른 코드’가 this를 명시적으로 바인딩한다면 그에 따라 this가 정해진다.

  • 콜백함수에 넣는 함수는 메서드의 형태처럼 보일 지라도 입력되는 값은 ‘함수’ 이기에 위의 thisBinding 법칙을 따르게 된다.

입력함수

  • 함수에서 뒤에 ()를 추가하면 () 내부의 인자들을 넣어 함수를 실행한 ‘결과’를 반환한다
    (함수 구조 자체 반환 X)

setInterval()

  • 반복해서 매개변수로 받은 콜백함수의 로직을 수행하는 함수
    => setInterval(콜백함수(function(){}), 반복 간격)

동기 / 비동기

  • 동기 : 순차적으로 일을 수행한 다음 다음 일을 시작하는 방식

  • 비동기 : 일의 순서와(완료여부) 상관없이 일을 계속해서 받고, 완료됐을 경우 반환하는 방식

  • 통신관련 코드는 대부분 비동기 방식을 차용함

참고사진 출처 : https://smallzoodevs-organization.gitbook.io/copy-of-javascript-study/day-05./1.

비동기의 단점 => 콜백지옥

  • 콜백 함수를 익명 함수로의 전달 과정이 반복되면 들여쓰기 수준이 “지옥” 수준이 된 경우

  • 비동기 작업에서 동기 작업같이 순서를 정해주는 과정에서 일어나는 현상

참고사진 출처 : https://dev.to/jerrycode06/callback-hell-and-how-to-rescue-it-ggj

비동기의 개선 - 순서 보장(동기적 표현)

  1. Promise / then(다음)

    • new Promise(콜백함수)를 이용해 호출한 콜백함수는 비동기적으로 실행되지만, 순서가 보장되게 된다.

    • 콜백함수의 성공 여부에 따라 resolve/reject 를 반환한다
      => 이를 이용해 then(성공) / catch(실패) / finally(상관없음) 로 이후 동작을 제어한다

    • 예제

     //리팩토링 전 콜백 지옥
     setTimeout(
         function (name) {
             var coffeeList = name;
             console.log(coffeeList);
             setTimeout(
                 function (name) {
                     coffeeList += ", " + name;
                     console.log(coffeeList);
                     setTimeout(
                         function (name) {
                             coffeeList += ", " + name;
                             console.log(coffeeList);
                             setTimeout(
                                 function (name) {
                                     coffeeList += ", " + name;
                                     console.log(coffeeList);
                                 },
                             500,
                             "카페라떼"
                             );
                         },
                     500,
                     "카페모카"
                     );
                 },
             500,
             "아메리카노"
             );
         },
         500,
         "에스프레소"
     );
    
     //promise를 이용한 리팩토링
     var addCoffee = function (name) {
         return function (prevName) {
             return new Promise(function (resolve) {
                 setTimeout(function () {
                     var newName = prevName ? `${prevName},  ${name}` : name; 
                     // 삼항 연산자로 prevName의 여부에 따라 값을 다르게 저장
                     console.log(newName);
                     resolve(newName); 
                     // resolve를 통해 prevName에 newName 저장 closure와 연관 (후술)
                 }, 500);
             });
         };
     };
     addCoffee('에스프레소')()
     .then(addCoffee('아메리카노'))
     .then(addCoffee('카페모카'))
     .then(addCoffee('카페라떼'));
    
  2. Generator / next(다음)

    • 함수 뒤에 *을 붙여 제너레이터 함수로 만들고, 이러한 Generator 함수의 반환값은 Iterator 객체임

    • Iterator 객체는 .next()를 통해 순차적으로 실행을 제어함

    • next() 를 호출할 시 yield 를 써준 곳까지 실행한 후, 완료시 다음 yield로 이동함

  3. async(비동기) / await(기다리기) => Promise 반환

    • 함수 앞에 async를 적어주어 비동기 함수로 인식하게 함

    • 비동기 함수 내에서 await을 인식하면 거기서 멈춰 리턴 값을 기다리고 다음으로 이동

    • await에 Promise를 반환하는 함수가 있을 경우, 함수가 끝날 때까지 무조건 기다리게 됨
      (resolve 값을 기다림)

DOM

  • Document(html)를 Javascript가 이해할 수 있게 Object 형태로 Modeling 한 것

API

  • 다른 시스템에서 제공하는 기능을 사용할 수 있도록 도와주는 중간다리 역할

DOM 접근 및 제어

Class 와 Instance (객체 지향 언어의 공통점)

  • Class 는 제품의 설계도 / Instance는 설계도를 이용해서 만들어낸 제품1, 제품2, 제품3… 을 각각 지칭

  • class 에는 constructor(생성자 함수)가 존재하며 생성자 함수에는 ‘this.저장할 값 = 외부값(매개변수)’ 이 라는 형식으로 인스턴스(this)에 값을 부여해주는 역할을 한다.

  • 예제

class Person {
// 생성자 함수로 구조 지정 
constructor (name) {
this.name = name;
}
// 메서드 만들기
come() {
console.log(`${this.name} 등장`);
}
}

const person1 = new Person(""); //인스턴스 생성
person1.come(); //메서드 사용

Getters / Setters

  • 클래스를 통해 만든 객체(인스턴스) 내부의 프로퍼티(클래스 생성 때 사용한 입력해준 매개변수)를 제어하기 위함

  • 클래스 내부에 값을 불러오거나 저장하기 위한 메서드를 새로 정의 해주며, setters 의 경우 입력값의 유효성 검사 기능을 넣을 수 있다.

  • get / set 메서드 구성 시 모든 this.variable 에서 variable 앞에 (언더바)를 구성해주어 재귀함수가 되지 않도록 해준다.
    (
    (언더바)는 주로 Private(은밀성)을 표현할 때 사용한다.)

  • 예제

class Person {
constructor (name) {
this._name = name;
}
//setter
set name (value) {
    // 입력 값이 존재하며 string 일때만 저장하도록 유효성 검사
    if (value.length > 0 && typeof value === "string"){
        this._name = value;
    } else {
        console.log("[오류] 입력값을 확인해주세요!");
        return;
    }
};
//getter
get name () {return this._name};
}
//인스턴스 생성
const me = new Person("me")
//set
me.name = "bbie";
//get
let myName = me.name;

상속 (Inheritance)

  • class 선언 시 extends 를 통해 부모로 상속받을 class를 불러올 수 있음.

  • 상속받은 class(자식)는 기본적으로 부모 class의 구조, 메서드를 물려받으며 재정의(overiding) 할 수 있음

  • 자식 class 에서 구조(생성자 함수) 재정의 시 super(부모 class의 필요 매개변수) 를 통해 부모 class의 constructor(생성자 함수)를 불러올 수 있음

  • 예제

class HttpError extends Error { //extends Error => Error 객체를 부모로 상속
    constructor(response) {
        super(`${response.status} for ${response.url}`);
        //super => 부모 클래스의 생성자를 호출 Error(출력할 오류 메세지)
        this.name = 'HttpError';
        this.response = response;
        //추가 프로퍼티 초기화
    }
}

정적 메서드(Static Method)

  • class 내부에 있는 함수(메서드) 앞에 static(정적) 태그를 붙여주면 class명.메서드명(매개변수)로 인스턴스 생성없이 바로 실행 가능하다

  • 예제

//setter
class Person {
constructor (name) {
this._name = name;
}
//정적 메서드
static boom (name) {
    console.log(`${name}이 터졌습니다!`)
}
};

Person.boom("폭탄");

클로저(Closure)

  • 함수 선언 시의 LE(LexicalEnvironment => outer (외부 환경)) 의 수명이 다했음에도 여전히 참조 가능한 중첩함수를 지칭 ( 주로 return 되는 내부함수가 상위 scope(범위)의 변수를 참조할 때 )
    => 호출을 하는 외부 환경이 아님을 주의!

  • 주로 함수가 끝나도 계속해서 ‘저장하고 싶은 값’을 함수 외부에서 수정/접근하지 못하도록 하는데 사용함( Private(은밀성) 보장 )

  • 예제

//함수가 호출된만큼 카운트 하기
const increase = (function () {
// 카운트 상태 변수
let num = 0;
// 클로저
return function () {
    return ++num;
};
})();
// 이전 상태값을 유지한채로 증가
console.log(increase()); //1
console.log(increase()); //2
console.log(increase()); //3