이번 아티클에서는 앞서 살펴본 클로저의 정의에 해당하는 예제를 살펴보도록 하겠습니다. 우선, 아래의 예제 코드를 살펴보고 결과 값을 예측해보도록 합시다.
function outerFunc() {
var x = 10;
var innerFunc = function() {
console.log(x);
};
return innerFunc;
}
var inner = outerFunc();
inner();
앞서 살펴본 클로저 예제 유형과 비슷하면서도, 함수를 리턴하는 형식이 추가되었기 때문에 조금 어렵게 느껴집니다. 위 예제를 실행 컨텍스트와 변수 객체의 도식화를 통해서 표현하면 다음과 같습니다. 도식에 대한 설명은 차근차근 짚어나갈 테니, 바로 이해가 가지 않는다고 너무 걱정하지 맙시다.
간단하지만, 개념이 아직 잡혀있지 않으면 꽤 어렵게 느껴질수도 있는 도식입니다. 자, 여기서 만약에 innerFunc( ) 함수가 outerFunc( ) 함수 내에서 실행이 되었다면 별다른 문제가 없었을 것입니다. outerFunc 실행 컨텍스트에서 innerFunc 실행 컨텍스트가 생성되고, 거기에 맞춰 스코프 체인이 형성되는 구조는 우리가 학습한 기본적인 구조입니다.
하지만 여기서 기본 예제와 근본적인 차이가 발생합니다.
첫째, innerFunc는 outerFunc 컨텍스트 내에서 선언만 되고, 실행되지 않습니다.
둘째, innerFunc라는 함수 자체는 전역 컨텍스트의 inner 변수로 리턴됩니다.
셋째, inner라는 함수 변수를 통해 결과적으로 innerFunc( )라는 함수는 전역 컨텍스트에서 실행이 됩니다.
자, innerFunc( ) 라는 함수가 실행된 상황을 생각해보면 outerFunc라는 함수 본인이 선언된 컨텍스트를 벗어났습니다. 하지만 위의 도식에서 보는 것과 마찬가지로, innerFunc의 [[scope]]에는 전역 객체 / outerFunc 변수 객체 / innerFunc 변수 객체가 그대로 남아있습니다. 마치 outerFunc 실행 컨텍스트에서 실행된 것과 마찬가지로 말이죠.
여기서 innerFunc( )는 outerFunc( )에 선언된 지역 변수인 x를 그대로 참조합니다. 즉, 어떤 (내부)함수가 최종적으로 리턴되더라도 변수 객체는 (내부 함수의)스코프 체인에 그대로 남아 참조를 그대로 하게 되는 것을 의미합니다. 즉, 원칙적으로는 참조할 수 없는 컨텍스트인 외부 함수의 변수를 참조하는 함수를 클로저라고 칭하게 되는 것입니다.
여기 예제에서 쉽게 설명하면, innerFunc( )라는 함수는 outerFunc( )라는 "외부"함수의 변수인 x를 참조해 마치 자신이 outerFunc( ) 내부 함수로서 실행되었을 때와 같은 결과를 가져옵니다. 왜냐하면, 스코프 체인이 그대로 유지되기 때문에 x가 innerFunc( ) 내에 선언되어 있지 않음을 확인하고, 차례로 outerFunc 변수 객체까지 거슬러 올라가기 때문이죠.
여기서 [클로저가 참조하는 외부의 변수] x와 같은 변수를 자유 변수(free variable)라고 칭하며, 이 자유 변수와 엮여있는(가까운, 폐쇄된) 함수를 클로저로 칭하게 되는 것입니다.
'Programming > Javascript' 카테고리의 다른 글
12. Javascript 클로저(Closure)(2) - 클로저의 활용 1 (0) | 2022.11.21 |
---|---|
12. Javascript 클로저(Closure)(1) - 클로저의 정의 3 (0) | 2022.11.19 |
12. Javascript 클로저(Closure)(1) - 클로저의 정의 1 (2) | 2022.11.14 |
11. Javascript 실행 컨텍스트(4) - 스코프 체인 3 (0) | 2022.11.12 |
11. Javascript 실행 컨텍스트(4) - 스코프 체인 2 (0) | 2022.11.10 |