Hoisting
- hoisting : "끌어올린다"를 뜻하며 python과 다르게 선언된 var변수와 함수가 밑에있어서 위로 끌어올려서 사용하는 것.
 
- 편리하긴 하지만 일반적인 논리순서( 선언-> 초기화-> 사용 )가 아니기에 되도록 피하는 것이 좋다!
 
선언 만이 hoisting 대상이다.  
- 따라서 이것만 기억하면된다.
변수는 let과 const만 쓸것.
함수는 함수표현식으로 쓸것. 
(x)
function 함수(){
  로직
}
(o)
let 함수 = function(){
  로직
}
TDZ(time dead zone)
- "time" 인 이유는 사각지대(dead zone)가 코드의 작성 순서가 아니라 코드의 실행 순서에 의해 형성되기 때문이다. 
 
{
    
    const func = () => console.log(letVar); 
    
  
    let letVar = 3; 
    func(); 
}
Scope
const, let
- Global scope
Function scope
Block scope 
- 다른 언어는 전역변수와 지역변수인 반에 JS는 블록레벨이 추가로 더 있다.
 
var
- Global scope
Function scope 
- 타 언어와 같이 전역변수와 지역변수로 동작함. 블록레벨이 사라짐.
 
동기, 비동기
- JS도 타 언어와 같이 동기로 코드를 구성하되 아무거나 비동기로 하는것이 아닌 다음과 같은 것(시간이 오래걸리는 거)들만 비동기로 처리하는 것을 추천한다.
 
- Rest API 요청
 
- file/BD 처리
 
- 타이머, 암호화 / 복호화
 
setTimeout()
setTImeout(함수, milliseconds)
비동기의 문제점
- Rest API의 결과값을 받아서 이를 기반으로 코드를 실행할 때 결과값을 받지 않은채로 다음 코드가 실행될 수 있다.
 
- 그래서 Vanilla JS에서는 axios를 사용한다!
 
call back 함수
- JS함수는 first-class function이다. 
 
first-class function
- 함수 자체를 변수에 저장가능
 
- 함수의 인자에 다른 함수를 매개변수로 전달가능
 
- 함수의 return에 다른 함수를 return 가능
 
Promise
- 무한 콜백함수를 넣을 수 있는 콜백함수의 단점을 극복하기위해 나온 문법
 
- Promise 객체를 생성하고
 
- Promise객체는 executor라는 함수가 자동으로 실행되고 executor함수가 resolve와 reject 함수를 인자로 받아 비동기 처리 함수를 실행
 
- executor를 통해 비동기 처리 함수를 실행 완료 후 해당 작업이 성공하면 resolve 실패하면 reject를 호출한다.
 
promise의3가지 state
- Pending : 비동기 처리가 아직 실행되지 않은 초기상태
 
- Fulfilled : 비동기 처리가 성공적으로 완료된 상태
 
- Rejected : 비동기 처리가 실패한 상태
 
then method
promise.then(성공시함수, 실패시함수)
- 작업 성공 또는 실패시 수행할 작업을 정의하고 promise 코드를 실행해주는 method이다.
 
- 이때 매개변수는 2개(성공, 실패)이다.
 
const promise = new Promise(
  (res, rej) => {
    setTimeout(() => {
      let num = 10;
      if (num > 9) {
        res(num);
      } else {
        rej("error");
      }
    }, 1000);
  }
);
promise.then((성공함수이름) => {
  console.log("success", 성공함수이름);
}, (실패함수이름) => {
  console.log(실패함수이름);
});
chaining
- 만약 위의 코드에 동기코드를 한개 더 붙이고 싶다면 
 
const promise = new Promise(
  (res, rej) => {
    setTimeout(() => {
      let num = 10;
      if (num > 9) {
        res(num);
      } else {
        rej("error");
      }
    }, 1000);
  }
);
promise.then((성공함수이름) => {
  console.log("success", 성공함수이름);
}, (실패함수이름) => {
  console.log(실패함수이름);
}).then(() => {
  성공로직
}, () => {
  실패로직
});
- 만약 .then() 뒤에 success 함수만 넣어놓을 경우 당연하게도 나머지 함수들은 실행이 안 된다.
 
catch method
- 실행중 예외 상황을 처리
 
- failureCallback이 정의되있지 않을 경우 reject 시에 catch method를 호출한다.
단, filureCallback이 정의되어있다면 catch method는 실행되지 않는다. 
const promise = new Promise(
  (res, rej) => {
    setTimeout(() => {
      let num = 10;
      if (num > 9) {
        res(num);
      } else {
        rej("error");
      }
    }, 1000);
  }
);
promise.then((성공함수이름) => {
  console.log("success", 성공함수이름);
})
.catch((err) => {
  console.log(error);
});
throw
throw new Error("~~에러")
const promise = new Promise((res, rej) => {
  console.log("start");
  res(1);
});
promise.then((num) => {
  console.log("성공1");
})
  .then(() => {
    console.log("성공2");
    throw new Error("에러");
  })
  .then(() => {
    console.log("성공3");
  })
  .catch((err) => {
    console.log("에러");
  });

chaining과 return
- 만약 .then() method의 결과값을 return 했다면 그 값은 바로 다음 .then()의 매개변수로 들어간다.
 
finally
- switch문의 default 포지션과 같다. 
 
- 그런데 우선순위가 항상 제일 마지막은 아니다. 만약
 
promise.then(()=>{
  로직~
  throw new Error("에러");
})
.then(~~함수~~)
.finally(~~함수~~)
.catch(~~함수~~)
       
1번 then
finally 함수
catch 함수
Promise.all
- 동기화 처리할 promise를 한큐에 묶어서 실행
 
const promise = new Promise(~~함수~~);
const promise2 = new Promise(~~함수~~);
Promise.all([promise, promise2]).then(~~함수~~)
Promise.race
- 여러 promise 함수중 가장 빨리 실행된 함수만 then에 실행될 수 있음.
 
const promise = new Promise(~~함수~~);
const promise2 = new Promise(~~함수~~);
Promise.race([promise, promise2]).then(~~함수~~)