Skip to content

Instantly share code, notes, and snippets.

@snaag
Created May 13, 2020 09:46
Show Gist options
  • Save snaag/088a49ebb728a9e6613a883ce5157175 to your computer and use it in GitHub Desktop.
Save snaag/088a49ebb728a9e6613a883ce5157175 to your computer and use it in GitHub Desktop.

들어가며

클로저에 관한 내용입니다. 개념 위주로 작성하였습니다.

Closure

책과 여러 자료를 보고 정리 해봤을 때, 클로저는 아래와 같은 개념을 말한다고 나름의 정리를 해봤다.

클로저는 함수 자신과 함수 자신이 선언된 어휘적 환경을 기억하고 있다.

따라서 생명주기가 끝난 외부 함수의 변수를 스코프 체인 을 통해서 참조 를 할 수 있다.

코드를 보자.

function outerFunc() { // 외부 함수
  var x = 10;
  function innerFunc() {
    console.log(x);
  }
  return innerFunc;
}

var inner = outerFunc();
inner(); // 10

ffInner = fOuter() 를 했을 때, fOuter()의 execution context 는 call stack에서 사라졌다. 왜냐하면 자신이 할 일을 다 했기 때문이다.

그렇다면 ffInner() 는 어떻게 vOuter 를 출력할 수 있을까? vOuterfOuter 안에 있는데?

먼저 이런 상황, fOuter 가 자신의 일을 다 해서 call stack에서 사라진 경우를 fOuter의 생명주기가 끝났다 라고 한다. 따라서 존재하지 않기 때문에, 일반적으로는 값을 참조할 수 없다. 그럼 어떻게 참조를 한걸까?

답은 변수 객체와 스코프 체인이다.

변수 객체, 스코프 체인

closure

-참고3

실행 컨텍스트와 활성 객체에 대한 설명은 이 자료 에 있다.

이때 funcOuter() 가 자신의 일을 다 했어도, funcInner() 가 자신의 스코프안에 있는 x 를 참조하기 때문에, funcOuter() 의 실행컨텍스트 는 사라져도 funcOuter()의 변수 객체(활성 객체) 는 살려둔다.

따라서, inner(); 를 실행했을 때 funcOuter()의 변수 객체 에 접근함으로써 funcOuter() 내의 identifier 들을 참조할 수 있는 것이다. 그리고 이 때 참조는 스코프 체인 을 통해 이루어진다.

스코프 체인은 스코프가 연결되어있다는 말인데, 그렇다면 어떻게 연결되어있을까?

내부구조

함수가 생성되면 Execution Context 가 생성되고, 그리하여 Lexical Environmentouter Lexical Environment 가 상위 Environment Record 와 연결되면서 내부 함수 정보를 탐색할 수 있게 됩니다.

-참고4

즉 Execution context가 만들어질 때, (그 안에서) 외부로 접근할 수 있는 outer 와 식별자들의 바인딩을 기록하는 객체인 Environment Record 가 만들어진다. 따라서 outer 를 통해서 상위 Environment Record 에 접근하여 임의의 식별자에 접근할 수 있는 것이다.

참고자료

  1. You Dont' Know JS (1)

  2. 인사이드 자바스크립트

  3. https://poiemaweb.com/js-closure

  4. https://knphouse.co.kr/91?category=693064

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment