[JavaScript] 클로저(Closures) - 활용편(1/2)
이전 포스팅에서 클로저의 개념을 살펴보았다. 이번 포스팅에서는 배웠던 개념을 바탕으로 클로저의 예시와 활용법에 대해서 알아보고자 한다.
클로저 예시 1 코드
let f;
const g = function () {
const a = 23;
f = function () {
console.log(a * 2);
}
}
g();
f();
클로저 예시 1 코드 해석
해당 코드를 콘솔창에서 실행했을 경우 '46'이라는 결과값을 얻게 된다. f 함수는 어떻게 g의 'a'라는 변수에 접근할 수 있을까?
'g()'를 실행했을 때 'a'는 23이되고, 'f'는 함수라는 것까지 정의된다. 이후 'f()'가 실행되면서 '46'이 나온다. 이 과정을 자세히 살펴보면 f 함수에 정의된 실행 컨텍스트의 모든 변수가 클로저로 연결(Close Over)된다는 것이다. 이는 변수 그 자체일 때도 해당된다. 'let f' 변수를 살펴보면 기술적으로 변수 환경 안에서 정의되지 않고, 바깥 Global Scope에서 정의 되었고 생성되었다. 이후 g 변수에 함수를 할당하듯이 g함수의 변수 환경이 f의 function에 Close over 된다. 이때 'const a = 23' 변수도 포함된다. 따라서 g 함수가 실행된 이후에도 'a'라는 변수에 접근할 수 있는 것이다.
f 함수를 실행할 때 g의 변수환경은 더 이상 존재하지 않는다. 하지만 f 함수는 해당 변수 환경을 Close Over 한다. 따라서 a 변수에 접근할 수 있다. 이전 포스팅에서 클로저를 배낭에 비유한 적이 있다. 그것과 같이 a 변수는 f 함수의 배낭에 있는 것이다. 다른 예제를 더 살펴보자.
클로저 예시 2 코드
let f;
const g = function () {
const a = 23;
f = function () {
console.log(a * 2);
}
}
const h = function () {
const b = 777;
f = function () {
console.log(b * 2);
}
}
g();
f();
h(); // Re-aasigning f function
f();
클로저 예시 2 코드 해석
두번째 f 실행의 결과는 '1554'가 나온다.
h 함수를 실행함에 따라 f가 다시 할당된다. 주의해야할 점은 첫번째 f() 실행의 함수와 두번째 f() 실행의 함수가 다르다는 것이다. h 함수를 실행하면서 f는 h의 변수환경을 Close over했다는 점을 알 수 있다. 그래서 777로 설정된 b 변수에 접근할 수 있는 것이다. 'console.dir(f)'를 입력하여 변수 환경을 실제로 확인해보자.
a는 사라지고 b만 존재하는 것을 알 수 있다. h 함수로 f 변수가 재할당 되기 전에 'console.dir()'을 통해 확인하면 클로저에 a 변수만 존재하는 것을 알 수 있다. 클로저가 발생지(Birth Place)에 있는 변수와 기능을 연결한다는 사실을 재확인할 수 있다.