메뉴 닫기

[javascript]실행문맥과 closure

자바스크립트를 공부중이다.

자바스크립트는 scope 에 대해 다른 언어들과 다른 특징을 가지는데

먼저 유효범위에 있어서

  1. 블럭 범위가 아닌 함수 범위이다.
  2. 중복된 변수명의 경우 현재 실행문맥의 활성화 객체에서 먼저 찾는다.
  3. 유효범위가 실행환경이 아니라 함수 정의환경이다

자바스크립트는 실행 될때 실행문맥을 생성해서 자바스크립트의 콜스택에 쌓는다.

그럼 실행문맥은 무엇일까?

실행 문맥은 자바스크립트 함수가 실행될때 필요한 정보들을 담고 있는 객체라고 생각하면 된다. 실행 문맥속에는 활성화 객체(변수,함수 등의 정보), 유효범위(chain scope),this 객체를 가진다.

위의 코드가 실행 될때 자바스크립트는 전역컨택스트를 생성하여 콜스택에 쌓는다.

전역 객체에는 o, F1 이 존재하고

다음으로 F1() 이 실행 될때 F1 실행 컨택스트를 콜스택에 쌓는데

이때 실행 문맥에는

  1. 활성화객체 – a :10 , F2
  2. scope chain – 0(0번은 전역)
  3. 이 시점의 실행문맥을 this 에 바인딩 – this.a , this.F2()

그리고 F1이 실행되면서 F2가 실행 되는데 다시 콜스택에 F2의 실행 문맥이 쌓이고

F2의 실행문맥은

  1.  활성화 객체
  2. scope  chain – 0(전역) , 1(F1)
  3. this

로 구성된다.

이런 자바스크립트의 scope가 중요한 이유는 closure라는 개념 때문인데

기본적으로 자바스크립트는 garbage collector를 사용하는 언어이다.

따라서 더이상 사용(참조)되지 않는 변수는 가비지 컬렉션 대상이 되어 메모리에서 해제된다.

하지만 closure를 사용한다면

function 1(){

function 2(){
}

}

1번 함수 가 종료 된 후에 2번 함수가 실행 될때, 1번 함수의 변수를 참고하고 있다면(scope chain 에 의해 해당 변수를 사용 가능) 1번 함수는 가비지 컬렉션 대상이 되지 않는다. 결국 2번 함수의 의해서 1번함수는 닫힐수 있게 되는데 이때 2번함수는 closure가 된다.

이런 상황에서는 다음과 같은 몇가지 장점을 가질 수 있게 되는데

  1. 1번함수의 변수들은 외부에서 접글 할수 있다.(캡슐화)
  2. 각 변수는 해당 scope에서만 참조 되므로 전역변수의 남용을 막을 수 있다.
  3. 변수의 충돌을 막아 자바스크립트 모듈 패턴을 사용할수 있다.(라이브러리화)

하지만 closure는 단점도 존재한다. 1번함수가 가비지 컬렉션에 의해 메모리에서 해제 되어야 하나 계속 해제 되지 못하고 있을 경우 성능 저하의 문제가 된다. 또한 소스 를 파악하기 어렵다.