Week 1

jplendor·2022년 8월 10일
0

Closure

  • 기본적으로 "폐쇄"라는 의미를 가진 단어
  • 무엇이 폐쇄?
    함수가 선언될(혹은 생성될 때) 당시 주변 환경(Lexical Environment)와 함께 갇힘
    그래서 함수가 실행될 때, 그 환경에 대한 접근이 가능하다!

    실행되는 위치, 시점과 아무 관계없이
  • 사진 찍듯이 선언될 당시의 상황이 기억되는 것이 아니라,
    지속적으로 그 변화를 추적하게 된다. (Live Reference)

Garbage collector

  • 자바스크립트 미화원 (자바스크립트 엔진이 내부적으로 사용하는 메모리 관리 시스템, 우리가 사용하지 않는 값들에 대한 메모리 영역을 주기적으로 정리)
  • 클로저는 성능 관련 이슈나 메모리 누수의 가장 흔한 원인
  • 생성된 함수가 주변 환경에 대한 값을 지속적으로 사용하고 있을 수 있으므로,
    Garbage Collection에 의해 정리되지 않기 때문에
  • 개발자 도구 > Memory > Take heap(자바스크립트 메모리 공간) snapshot 또는
    개발자 도구 > Performace 확인
  • 성능에 예민한 상황(ex. 3D 게임, 내부 로직이 엄청 많은 증권거래소 등)에서 작업하는 경우를 제외하고 일반적으로 Garbage Collection에 대해 신경쓰지 않아도 된다.

Execution Context (실행 문맥)

  • 함수가 실행될 때마다 생성
  • Execution Context이 담고 있는 정보
    • 변수 정보 (일반 변수, 매개 변수, 함수 선언 등)
    • 스코프 정보 (상위 스코프에 대한 reference)
    • this 정보

Closure Quiz 1

for (var i = 1; i < 6; i++) {
  setTimeout(function timer() {
    console.log(i);
  }, i * 1000);
}

for문 시작
i=1, setTimeout 함수 실행 => timer 함수 선언 & 예약 (1초)
i=2, setTimeout 함수 실행 => timer 함수 선언 & 예약 (2초)
i=3, setTimeout 함수 실행 => timer 함수 선언 & 예약 (3초)
i=4, setTimeout 함수 실행 => timer 함수 선언 & 예약 (4초)
i=5, setTimeout 함수 실행 => timer 함수 선언 & 예약 (5초)
i=6, for문 종료
예약되었던 timer 함수 실행 => console.log(i); // 선언될 당시 주변 환경(전역)이 가지고 있는 i=6
예약되었던 timer 함수 실행 => console.log(i); // 선언될 당시 주변 환경(전역)이 가지고 있는 i=6
예약되었던 timer 함수 실행 => console.log(i); // 선언될 당시 주변 환경(전역)이 가지고 있는 i=6
예약되었던 timer 함수 실행 => console.log(i); // 선언될 당시 주변 환경(전역)이 가지고 있는 i=6
예약되었던 timer 함수 실행 => console.log(i); // 선언될 당시 주변 환경(전역)이 가지고 있는 i=6

Closure Quiz 2

function setTimer(j) {
  setTimeout(function timer() {
    console.log(j);
  }, j * 1000);
}

for (var i = 1; i < 6; i++) {
  setTimer(i);
}

setTimer 함수 선언
for문 시작
i=1, setTimer 함수 실행 => setTimeout 함수 실행 => timer 함수 선언 & 예약 (1초)
i=2, setTimer 함수 실행 => setTimeout 함수 실행 => timer 함수 선언 & 예약 (2초)
i=3, setTimer 함수 실행 => setTimeout 함수 실행 => timer 함수 선언 & 예약 (3초)
i=4, setTimer 함수 실행 => setTimeout 함수 실행 => timer 함수 선언 & 예약 (4초)
i=5, setTimer 함수 실행 => setTimeout 함수 실행 => timer 함수 선언 & 예약 (5초)
i=6, for문 종료
예약되었던 timer 함수 실행 => console.log(j); // 선언될 당시 주변 환경(setTimer 함수)가 가지고 있는 j=1
예약되었던 timer 함수 실행 => console.log(j); // 선언될 당시 주변 환경(setTimer 함수)가 가지고 있는 j=2
예약되었던 timer 함수 실행 => console.log(j); // 선언될 당시 주변 환경(setTimer 함수)가 가지고 있는 j=3
예약되었던 timer 함수 실행 => console.log(j); // 선언될 당시 주변 환경(setTimer 함수)가 가지고 있는 j=4
예약되었던 timer 함수 실행 => console.log(j); // 선언될 당시 주변 환경(setTimer 함수)가 가지고 있는 j=5


즉, 퀴즈 1과 퀴즈 2의 답에 차이가 나는 이유는?
퀴즈 1은 선언 당시의 주변 환경이 전역으로 동일하고 (i를 공유하고),
퀴즈 2는 서로 다른 setTimer 함수(실행 컨텍스트) 안에서 각각 선언되고, 그때의 j는 다 다르다. (j를 공유하지 않는다.)

재귀

  • The act of self-reference (스스로를 다시 부르는 행위)
  • ex. Life of Rabbit은 피보나치 수열로 표현할 수 있는데, 아래와 같은 점화식을 같는다.
    rabbits(n) = rabbits(n-1) + rabbits(n-2), rabbits(1) = 1, rabbits(0) = 0
    따라서, n번째 항의 값을 구하고자할 때, 재귀 함수를 써서 구할 수 있다.
  • 재귀함수를 구현할 때는 무조건 Termination Case(종료 케이스)을 넣어야 한다.
    (그렇지 않으면 무한히 호출)

Call stack

  • 함수 A가 호출되면, 해당 함수가 stack에 쌓인다.
  • 함수 A 실행 중에 함수 B가 호출되면 그 위에 쌓인다.
  • 함수 B가 종료되면 콜스택에서 함수 B가 제거된다.
  • 개발자 도구에서 확인해보기
function rabbits(n) {
  if (n === 0) {
    return 0;
  }

  if (n === 1) {
    return 1;
  }

  return rabbits(n - 1) + rabbits(n - 2);
}

debugger;

rabbits(3);

Recursion quiz

factorial 함수 완성시키기

function factorial(n) {
  if(n === 1) {
    return 1
  }
  return n * factorial(n-1)
}

const result = factorial(5);

console.log(result === 120);

HOF definition

  • Higher Order Function, 고차 함수

  • 함수를 인자로 받거나 함수를 반환하는 함수

  • 인자로 함수를 받지 않고 함수를 반환하지도 않는다면, 일차원 함수 (First Order Function) / 일반 함수

  • 예시

    function repeat(n, callback) {
      for (let i = 1; i <= n; i++) {
        callback(i);
      }
    }
    
    repeat(5, console.log);
    repeat(10, window.alert);
    repeat(20, console.warn);

    map

    const nList = [1, 2].map(function (val) {
    	return val + 3;
    });
    // [4, 5]

    reduce

    const result = [1, 2, 3].reduce(function (acc, val) {
    	return acc + val;
    });
    // 6

First class object

일급 객체의 조건

  • 인자로 전달할 수 있거나
  • 반환 값으로 사용될 수 있거나
  • 변수에 할당될 수 있거나, 자료구조에 저장될 수 있어야한다.

자바스크립트에서 함수는 위와 같은 작업이 가능하므로, 함수는 일급 객체이다.

profile
만들기는 재밌어!

0개의 댓글