[22-05-31 Vaco Prep TIL] Hoisting, Scope, Garbage Collector, Execution context, Closure

Jessie H·2022년 5월 31일
0

바닐라코딩 프렙

목록 보기
1/6
post-thumbnail

png created by here

22-05-30 바닐라코딩 프렙코스 OT
22-05-31 프렙코스 학습 시작


Hoisting과 Scope는 스타터 키트와 드림코딩 강의에서 배웠던 내용이지만 제대로 정리하지 않아 먼저 정리 후 Execution Context, Closure 순서대로 정리하려고 한다.




Hoisting

변수를 선언하고 초기화했을 때 선언 부분이 최상단으로 올라가는 현상.

var, let, const비교할 때 처음 배웠던 개념이다.


<script>
//Hoisting과 연관된 var, let, const의 차이

  console.log(a);
  var a = 1;
//var a;(a가 선언만 되고 할당되어지지 않은 상태, 즉 undefined인 상태)가
//최상단으로 끌어올려져서 undefined;가 출력된다.

  console.log(b);
  let b = 2;
//b를 선언하기 전 사용할 수 없다고 오류가 뜬다.
</script>

** 여기서는 함수와 관련된 Hoisting에 초점을 맞춰 공부한다.

함수를 함수선언식으로 표현할 경우, 함수는 선언과 동시에 초기화(초기값이 주어짐)된다.

<script>
  func();//콘솔창에 함수가 출력된다.
  function func(){
    console.log('함수');
  }
</script>

함수 func은 함수 선언식으로 표현되었기 때문에 hoisting이 가능해 함수가 선언되기 전에도 함수 func을 실행시킬 수 있다.




Scope

  • 기본적으로 {} 범위를 의미
  • {}, if(){}, for(){} 등등
  • local scope: {}안, 여기서 쓰인 변수는 선언된 {}범위에서만 사용 가능
  • global scope: {} 바깥, 여기서 쓰인 변수는 어디에서나 다 사용 가능
  • 렉시컬 환경(환경 레코드, 외부 환경 참조)을 object로 담고 있다.
    - 환경 레코드(environment record): 현재 {}에 대한 정보
    • 외부 환경 참조(Outer Lexical Environment Reference): 부모 {} 에 대한 정보

Scope Chain

<script>
  function outside() {
    let x = "안녕!";
    function inside() {
      console.log(x);
    }
    inside();
  }
  outside();//안녕!
</script>

위의 예제를 한 줄씩 보면

  1. outside();실행 위해 outside(){}로 이동
  2. inside();실행 위해 inside(){}로 이동 → console.log(x)실행 필요, inside()내에서 x 찾기 시도 → x값 없음
  3. 상위 스코프인 outside(){}에서 x찾기 시도 → let x = '안녕!' 발견, console.log('안녕!') 실행
  4. outside()실행 값은 console에 안녕!출력된 것으로 실행 종료

2, 3부분에서 inside()함수 실행 시 inside(){} scope에서 변수 x값을 찾을 수 없어 가장 가까운 상위 스코프로 이동하여 x를 찾은 것이 Scope Chain의 특징 때문!!

실행하는 함수 내부의 local Scope에서 먼저 찾은 후 그 변수를 찾을 때까지 상위 스코프를 계속 확인하는 것은 Scope Chain 특징 때문이다.





lexical Scope

  • 함수 선언 위치에 따라 상위 스코프를 결정하는 규칙.
  • 자바스크립트의 특징 중 하나

다음 예시 두 개로 lexical Scope 특징을 잘 알 수 있다.

<예제1>

<script>
  let x = "hello!";

  function func1() {
    let x = "안녕!";
    function func2() {
      console.log(x);
    }
    func2();
  }

  func1();
 </script>
  1. x = hello global scope에 저장
  2. func1() 환경 저장
  3. func1(); 실행
  4. func1(){}내부 읽기 시작 → func2()환경 저장, func2() 발견 → func2(){}내부 읽기 시작
  5. console.log(x) 실행 위해 변수 x func2()내부에서 찾기 → 없음 → 상위 scope인 func1()으로 이동
  6. x = '안녕!' 발견 → func2(){console.log(x)}실행
  7. console창에 안녕! 출력

<예제2>

<script>
  let x = 'hello!'

  function func1(){
    let x = '안녕!';
    func2();
  }

  function func2(){
    console.log(x);//func2()의 상위 스코프 = global scope, 따라서 x = 'hello!'
  }

  func1();//hello
</script>
  1. let x = 'hello!' global scope 데이터 저장
  2. func1, func2 함수 환경 저장
  3. func1(); 실행위해 다시 func1(){}로 이동
  4. local scope 변수 x = '안녕!' local scope 데이터로 저장
  5. func2() 실행 위해 func2(){}로 이동
  6. console.log(x) 실행 위해 변수 x func2(){}에서 찾기 시도 → 실패
  7. 상위 scope인 global scope로 이동, let x = 'hello!' 발견, console.log('hello!') 실행
  8. console창에 hello! 출력


Execution Context

  • Context = 코드 실행 환경
  • 자바스크립트는 하나의 실행 컨텍스트 스택을 가지고 있다.
    이런 모양이라고 생각하면 된다.

(사진출처 : https://hbase.tistory.com/122)

  • context 생성 시 context 내에는 arguments, variable, scope, chain, this가 생성된다.
  • 모든 코드는 처음 실행 시 global Context가 생긴다.
  • 함수1이 선언되면 global Context 안에 함수1에 대한 Local Context가 생긴다.
  • 함수 안에 또 다른 함수인 함수2가 선언되면 함수1 안에 함수2에 대한 local context가 생긴다.
  • 함수 실행이 끝나면 각 context는 사라진다.
    ex) 함수1 선언 시 함수1 context 생성 - 함수1 실행 후 함수1 context 사라짐



Garbage Collector

  • 자바스크립트 엔진에 내장, 백그라운드에서 동작
  • 변수 또는 배열, object, 함수 등 코드 중 어떠한 것도 가리키고 있지 않는 데이터를 청소
  • CPU를 사용하기 때문에 너무 많은 변수를 사용하면 Garbage Collector가 자주 작동되기 때문에 메모리가 낭비될 수 있다.
<script>
  let a = {name: 'data1', price: 3000,};
  let b = a;
  a = null;
  b = null;
  
  //{name: 'data1', price: 3000,}를 참조하는 변수가 없기 때문에 
  //이 데이터는 garbage collector의 청소 대상이 된다.
</script>


Closure

내부 함수에서 외부 함수 환경에 접근할 수 있게 기억하는 것을 말한다.

<예시>

<script>
  function outside() {
    let x = 3;
    function inside(y) {
      console.log(x, y);
    }
    return inside;
  }

  const insidefunc = outside();//insidefunc = function inside(y)
  insidefunc(3);
  
  // insidefunc(3) = inside(3) → console.log(x, 3)
  // Closure인 inside()(insidefunc) 덕분에 outside()함수에서 x를 찾을 수 있다.
  //insidefunc(3) = console.log(x=3, y=3);
</script>





참고 및 출처

profile
코딩 공부 기록장

0개의 댓글