teddy8 Full Stack Software Engineer

JavaScript 클로저(Closure)

2019-07-11
teddy8

클로저란?

함수가 정의될 때 렉시컬환경을 기억하는 함수를 말합니다.
간략히 아래의 예제로 살펴보겠습니다.

소스코드 — example.js

function createCounterClosure() {
	let count = 0;
	return {
		increase: function() {
			count++;
		},
    getCount: function() {
      return count;
    }
	}
}

const counter1 = createCounterClosure();
const counter2 = createCounterClosure();

counter1.increase();
counter1.increase();
console.log('counter 1의 값 : ' + counter1.getCount());
counter2.increase();
console.log('counter 2의 값 : ' + counter2.getCount());

실행 결과

counter 1의 값 : 2
counter 1의 값 : 1

객체지향프로그래밍에서 인스턴스와 비슷한 느낌입니다.
그럼 다른 예제도 보겠습니다.

example.js

for (var i = 0; i < 5; i++) {
	setTimeout(function() {
		i = 0;
		console.log(i);
	}, 1000)
}
위의 코드는 0 1 2 3 4를 출력할 것 같지만
5 5 5 5 5를 출력합니다.

이런 결과가 나타난 이유는 클로저는 외부 변수에 대해 값이 아닌 참조로 접근하기 때문입니다. 
즉, 클로저는 최종 갱신된 변수(i)에 대해서만 접근할 수 있으므로, 외부 함수가 전체 for문을 실행하고 
리턴한 최종 i의 값을 리턴하게 됩니다. 

example.js

for (var i = 0; i < 5; i++) {
	(function(j) {
		setTimeout(function() {
			console.log(j);
		}, 1000);
	})(i);
}
이런 부작용을 고치기 위해서 “즉시 호출된 함수 표현식(Immediately Invoked Function Expression. IIFE)”를 
사용할 수 있습니다. 이러면 i의 값이 j에 대입되어 0 1 2 3 4가 출력됩니다.

Similar Posts

Comments