Featured image of post Javascript - Closure

Javascript - Closure

자바스크립트 학습

클로저는 두개의 함수로 만들어진 환경으로 이루어진 특별한 객체의 한 종류이다. 여기서 환경이라 함은 클로저가 생성될 때 그 범위에 있던 여러 지역 변수들이 포함 된 context를 말한다. 이러한 범위는 자바스크립트 코드를 실행하기 위해 발생하는 컴파일 단계에서 결정된다.

클로저를 통해서 자바스크립트에는 없는 비공개 속성/메소드, 공개 속성/메소드 처럼 구현 할 수 있다.

Lexical Scope

자바스크립트 코드를 실행할 때 컴파일 단계에서 몇가지 일이 일어난다. 그중 하나인 토크나이징렉싱이 있다.

토크나이징

문자열을 나누어 토큰으로 만드는 과정

1
var num = 5;

위와 같은 구문을 만나게 되면, 아래와 같은 토큰으로 나눈다.

1
2
3
4
5
var
num
=
5
;

렉스타임

토크나이징의 결과물인 토큰을 분석하여 생성된 토큰에 의미를 부여하는 것렉싱이라고 하며, 이 과정을 렉스타임이라고 한다.

렉시컬 스코프

개발자가 코드를 작성할때 변수를 어디에 작성하는가를 바탕으로 렉스타임에 토큰이 분석되며 스코프가 결정된다. 이때 구성된 유효 범위를 렉스컬 스코프라고 한다.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
var a = 10;

function foo() {
	var b = 20;
	
	function bar() {
		var c = 30;
		colsole.log(a + b + c); // 60
	}

	bar();
}

foo();

위의 코드가 실행될때 스코프 버블은 bar 안쪽에서 부터 시작되어 올라간다.

코드를 해석하는 과정에서 상위에서 하위로 쌓이는 구조로 해석되기 때문에, scope에 대한 검색은 기본적으로 하위에서 상위는 되지만 상위에서 하위로의 검색은 불가능하다.

1
2
3
4
5
6
7
8
9
var a = 10;

function foo () {
	var b = 20;
	console.log(a); // 10
	console.log(b); // 20
}

console.log(b); // error

정리

컴파일레이션의 렉싱 단계에서 모든 변수들이 어디서 어떻게 선언되었는지 바탕으로 실행 단계에서 스코프를 구성하고, 이렇게 구성되는 스코프가 렉시컬스코프이다.

클로저 생성하기

  1. 내부 함수가 익명 함수로 되어 외부 함수의 반환값으로 사용된다.
  2. 내부 함수는 외부 함수의 실행 환경에서 실행된다.
  3. 내부 함수에서 사용되는 변수는 외부 함수의 변수 스코프에 있다.
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
function outer() {
  var name = `closure`;

  function inner() {
    console.log(name);
  }
  
	inner();
}

outer();
// console> closure

outer함수를 실행시키는 context에는 name이라는 변수가 존재하지 않지만, inner함수가 outer 함수 내부에 선언된 name을 참조하기 때문에, name 변수에 대한 정보를 알 수 없는 outer 변수 외부환경에서도 정상 출력된다.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
var name = `Warning`;

function outer() {
  var name = `closure`;

  return function inner() {
    console.log(name);
  };

}

var callFunc = outer();

callFunc();
// console> closure

위 코드에서 callFunc 를 클로저라고 한다. callFunc 호출에 의해 name 이라는 값이 console에 출력되는데, “Warning“이 아니라 “closure“이다. 즉, outer 함수의 context 에 속해있는 변수를 참조하는 것이다. 여기서 outer 함수의 지역변수로 존재하는 name 변수를 free variable(자유변수) 라고 한다.

이처럼 외부 함수 호출이 종료 되더라도 외부 함수의 지역 변수 및 변수 스코프 객체의 체인 관계를 유지할 수 있는 구조를 클로저라고 한다.