클로저(Closure)에 대해 공부하던 중, 문뜩 이런 생각이 들었다. 이거 정말 로맨틱한 녀석이잖아?
클로저는 떠나야되는 기차를 앞에 두고 서로를 놓아주지 않는 연인과도 같다.
function createLoversClosure() {
let lover1 = "외부 함수의 변수 (lover1)";
function loversRelationship() {
let lover2 = "내부 함수의 변수 (lover2)";
// 핵심 코드
console.log(`${lover2}는 ${lover1}을 떠나 보내지 않을거야!`);
}
// 클로저 반환
return loversRelationship;
}
// 클로저 생성
let loversClosure = createLoversClosure();
// 클로저 호출
loversClosure();
코드의 구조는 아래와 같다.
createLoversClosure
은 내부 함수 loversRelationship
을 감싸고 있다.
내부 함수 loversRelationship
의 console.log()
는 외부 함수의 변수 lover1
을 참조하고 있다.
외부 함수는 내부 함수를 return
하며, 이 반환값을 최상위 스코프의 변수 loversClosure
에 할당한다.
즉, loversClouser
를 호출하는 것은 내부 함수 loversRelationship
을 실행하는 것과 같다.
loversClouser
는 언제나 lover1
을 열정적으로 끌어 안은 채 (참조 하며) 호출된다.
로맨틱의 핵심은 외부 함수의 변수
lover1
을 참조하고 있는 내부 함수의console.log()
다. 즉 저 핵심 코드가 없다면...
function createLoversClosure() {
let lover1 = "외부 함수의 변수 (lover1)";
// 내부 함수는 더 이상 외부 변수를 참조하지 않는다.
function loversRelationship() {
let lover2 = "내부 함수의 변수 (lover2)";
console.log(`${lover2}: lover1, 너는 차였다.`);
}
return loversRelationship;
}
let brokenLovers = createLoversClosure();
brokenLovers(); // 더 이상 로맨틱 하지 않게 되는 것이다.
로맨틱과 안 로맨틱은 유사해 보이지만 분명한 차이점이 있다.
내부 함수
loversRelationship
은 외부 변수lover1
에 접근할 수는 있으나 참조하지는 않는다는 점이다.
만약 클로저가 안 로맨틱 하다면 어떻게 될까?
lover1
은 마침내 알아차렸다. 아무도 그를 필요로 하지 않는다는 사실을... lover1
은 알잘딱깔센 하게 떠난다. 어디로? 가비지 콜렉터로...
안 로맨틱한 클로저들의 무덤, 가비지 콜렉터(Garbage Collector)
가비지 콜렉터는 더 이상 사용되지 않는 메모리를 정리하고 회수하는 역할을 한다. 즉, 안 로맨틱한 클로저에서 더 이상 참조되지 않는 메모리 lover1
를 회수하고, 시스템 자원을 효율적으로 관리한다. 불필요한 것이 없는 깨끗한 세상이 된 것이다. Hello, Clean World!
코드의 세계에서도 솔로들의 삶은 애석하다.