자바스크립트 클로져 아주쉽게 이해하기

자바스크립트의 클로져는 생각보다 간단하다.

진짜다. 사실임을 아래에서 보여주고자 한다.

그런데 이 글을 이해하기 위해서는 스코프라는걸 알아야한다.

스코프 또한 너무 간단하게 설명이 될수 있고 자바스크립트 스코프에 대해 아주쉽게 이해하기 글에서 확인해볼 수 있다.

 

아래와 같이 { } 로 공간을 만들어서 그 안에 box 변수를 만든다

그러면 box 변수는 { } 공간 안에서만 유효하고 { } 공간 밖에서는 없는셈이다

ew0KICAgbGV0IGJveCA9IDEyMzsNCn0=
{ let box = 123; }

 

box 는 { } 안에서만 유효하기에 4번라인에서 접근하는것은 불가능하다

즉 4번라인이 실행되는 시점이라고 한다면 이미 2번라인에서 { } 안에 만들어진 box 변수는 사라지고 난 뒤가 된다

ew0KICAgbGV0IGJveCA9IDEyMzsNCn0NCmNvbnNvbGUubG9nKGJveCk7
{ let box = 123; } console.log(box);

 

아래의 코드를 보자

fff 변수 안에 넣어준 함수를 6번라인에서 처럼 실행하게 되면 해당 함수가 실행되어 4번라인을 실행하게된다

4번라인을 실행할때 box 변수가 어디에 있는지를 찾아보게 된다. 일단 console.log 코드가 포함된 공간 { } 에서 box 를 찾아본다.

하지만 없다. 그래서 범위를 상위로 넓혀서 찾아본다. 찾아보니 2번라인에 존재한다. 그래서 123을 콘솔에 찍게된다.

그런 후 함수는 종료되고 8번라인을 실행해서 Hello 를 찍는다.

8번라인을 실행하는 시점에는 이미 { } 를 빠져나온 시점이기 때문에 fff, box는 이미 무효하게 사라지게 된 상황이다

ew0KICAgbGV0IGJveCA9IDEyMzsNCiAgIGxldCBmZmYgPSBmdW5jdGlvbiAoKSB7DQogICAgICBjb25zb2xlLmxvZyhib3gpOw0KICAgfTsNCiAgIGZmZigpOw0KfQ0KY29uc29sZS5sb2coJ0hlbGxvJyk7
{ let box = 123; let fff = function () { console.log(box); }; fff(); } console.log('Hello');

 

아래와 같이 바꿔보자

위의 코드와의 차이점은 fff 변수를 만드는 공간을 8번라인 코드에서 접근할 수 있는 공간에 만들었다.

2에서 7번까지의 라인은 fff 변수를 만든공간의 하위에 만든 새로운 공간이다.

이 새로운 공간을 "안쪽공간" 이라고 부르겠다

"안쪽공간" 은 밖깥쪽 공간에서 접근할 수 없는 "폐쇄적 공간"이다.

Closure 는 영어사전에 폐쇄라고 나온다

"안쪽공간"에서 3번라인에 box 변수를 만든다.

그리고 "안쪽공간"보다 상위공간에 만들어 둔 fff 에 4번라인에서 함수를 만들어서 넣어준다.

함수를 넣어주고나면 "안쪽공간"의 영역은 끝나게 되고 8번라인 상위공간에 있는 Hello 찍는 코드를 실행한다

Hello 를 찍는 시점에서는 위의 코드에서라면 box 변수는 이미 사라진 상태였다. 위의 코드에서 fff 도 사라진 상태였다.

하지만 아래 코드에서는 fff 는 8번라인과 동일한 공간에 존재하는 변수이기에 8번라인 실행하는 시점이라 해도 사라지지 않는다.

그리고 fff 안에는 "안쪽공간" 에서 넣어준 함수가 들어있다.

 

그렇다면.. box 는 사라졌을까?

이제 9번라인에서처럼 fff 함수를 실행해보자

fff 함수를 실행한다는 뜻은 5번라인을 실행한다는 뜻이다.

만약 box 가 사라졌다면 123은 찍힐수 없다.

 

하지만 찍힌다.

 

이 함수는 box 가 사라졌다면 정상작동 할 수 없다.

이 함수와 box는 서로 연관성이 생기게 된것이다.

box 와의 연관이 맺어져있는 이 함수가 "안쪽공간"의 밖깥쪽에 있는 fff변수와 연결되어있기 때문에 box 는 살아있을 수 밖에 없는 것이다

10번라인에 setTimeout 으로 10초후에 fff 함수를 실행하게 해보았다. 1에서 9번라인까지의 실행은 0.001초 내에 이미 수행이 다 끝날것이다.

그런 후 10초 후에 fff 함수를 실행해보는 것이다. fff 가 사라지지 않는 한 box 는 계속 살아있게된다. 그래서 10초 후에 123은 찍힐것이다.

bGV0IGZmZjsNCnsgLyog7JWI7Kq96rO16rCE7J2YIOyLnOyekSAqLw0KICAgbGV0IGJveCA9IDEyMzsNCiAgIGZmZiA9IGZ1bmN0aW9uICgpIHsNCiAgICAgIGNvbnNvbGUubG9nKGJveCk7DQogICB9Ow0KICAgLyog7JWI7Kq96rO16rCE7J2YIOyLnOyekSAqLyB9DQpjb25zb2xlLmxvZygnSGVsbG8nKTsNCmZmZigpOw0Kc2V0VGltZW91dChmZmYsIDEwMDAwKTs=
let fff; { /* 안쪽공간의 시작 */ let box = 123; fff = function () { console.log(box); }; /* 안쪽공간의 시작 */ } console.log('Hello'); fff(); setTimeout(fff, 10000);