TodayILearned/javascript

실행컨텍스트와 클로저

tuigun 2021. 6. 25. 17:33
poiemWEB,제로초님의 블로그글을 읽고 공부한 내용을 정리했습니다.

실행컨텍스트 

실행 가능한 코드를 형상화하고 구분하는 추상적인 개념

브라우저가 스크립트를 실행하는 순간, 전역 컨텍스트가 생성됨( 모든것을 관리하는 환경)
이후 함수를 호출할 때 마다 함수 컨텍스트가 하나씩 생성된다.

컨텍스트의 네가지 원칙

  1. 전역 컨텍스트 생성 후, 함수 호출 시 마다 컨텍스트가 생성
  2. 컨텍스트 생성 시 컨텍스트 안에 변수객체(variavle, argument), scope chain, this가 생성됨
  3. 컨텍스트 생성 후 함수 실행, 사용되는 변수들을 변수 객체 안에서 찾고 없다면 스코프 체인을 따라 올라가며 찾는다.
  4. 함수 실행이 마무리되면 해당 컨텍스트는 사라짐(클로저 제외) 페이지가 종료되면 전역 컨텍스트는 사라짐.
var x = 'xxx';

function foo () {
  var y = 'yyy';

  function bar () {
    var z = 'zzz';
    console.log(x + y + z);
  }
  bar();
}
foo();

전역컨텍스트

전역 컨텍스트는 argument가 없고, variable은 해당 스코프의 변수들이다. scope chain은 자기 자신인 변수 객체.
this 따로 설정되어있지 않으면 자기 자신이다.
'전역컨텍스트' : {
	변수객체: {
    	argument: null,
        variable: [x,y,z,foo,bar],
    },
    scopeChain: ['전역변수객체']
    this: window,
  }

함수 컨텍스트

'foo 컨텍스트': {
	변수객체: {
    arguments: null,
    variable: y, bar, z
    },
    scopeChain: ['전역변수객체', 'foo변수객체'],
    this: window,
  }
   
'bar 컨텍스트' : {
	변수객체: {
    arguments: null,
    variable: [z],
    },
    scopeChain: ['전역 변수객체','bar 변수객체','foo변수객체'],
    this: window,
  }

코드를 따라 실행 컨텍스트가 쌓이게되고(main > foo() > bar()),  foo 함수가 실행된 후 bar함수가 실행된다. bar 컨텍스트 안의 console.log의 x,y,z는 bar컨텍스트 안에서 찾는다. z는 찾았지만 x,y는 전역변수 객체와 foo변수객체에서 찾는다. 

x= xxx, y= yyy

bar함수가 실행된 후 스택에서 삭제되고, foo컨텍스트 스택이 삭제되고, 마지막에 전역 컨텍스트도 삭제된다.

클로저

함수를 일급 객체로 하는 함수형 프로그래밍 언어의 특성.
반환된 내부함수가 자신이 선언됐을 때 환경인 스코프를 기억하여 자신이 선언됐을 때의 환경(렉시컬 환경)을 기억하여, 자신이 선언됐을 때의 환경(스코프) 밖에서도 그 환경에 접근할 수 있는 함수.

즉 클로저는 자신이 생성될 때의 환경(렉시컬 환경)을 기억하는 함수다.

실행 컨텍스트의 관점에서 외부함수가 종료되어 반환돼도, 외부함수 실행 컨텍스트의 활성객체(Activation Object)는 내부함수에 의해 참조되는 한 유효하며, 내부함수가 스코프체인을 통해 참조할 수 있는것을 의미한다.

클로저는 렉시컬 환경을 기억해야하므로 메모리적 손해를 볼 수 있지만, 현재 상태를 기억하고 변경된 최신상태를 유지하는 기능이 있다.
클로저로 생성된 변수는 private변수로, 전역변수를 사용했을 때와 같이 의도치않은 변경에 대한 걱정이 없다. 따라서 안정적인 프로그래밍이 가능하다.

reference : 

https://poiemaweb.com/js-eecution-context

https://www.zerocho.com/category/Javascript/post/5741d96d094da4986bc950a0