for (var i = 0; i < 5; i++) {
  (function(j) {
    $('#target' + j).on('click', function() {
      alert(j);
    });
  })(i);
}

 

클로저로 for문으로 이벤트리스너를 연결하는 방법은 위와 같다고 한다. 

패턴은 그렇지만 이유를 알아보자.

 

2~6번째줄의 즉시실행함수는 한번 실행 후 다시 부를 방법이 없다(끝이 난다).

즉, i가 j로 대입되고 한번 실행된 후 바로 바깥쪽 for문의 i와의 연결고리는 끊기게 된다.

(function () {

 var j = i;

 ...

})();

와 같다고 보면 좀더 이해하기 쉬울 것이다. (j는 고정값이 된다는 뜻)

 

3번째줄 이벤트리스너 안쪽의 function ()은

for문 안에서 매번 선언될 때 변수에 대한 scope를 갖게 되는데 (선언될때=렉시컬스코프)

바로 바깥쪽 function (j)의 스코프를 상위 스코프 체인으로 계속 갖고 있게 되므로 

고정된 j 값을 가질 수 있게 된다.

j는 이벤트 리스너 안의 function () 의 비공개변수가 되는 것이다.

달리 말해 이벤트리스너 안의 function ()의 클로저가 생성되었다고 할 수 있다.

 

for (var i = 0; i < 5; i++) {
  var makeEventListener = function() {
  	var j = i;
	return function () {
    	$('#target' + j).on('click', function() {
      		alert(j);
    	});
    }
  };
  var _eventListener = makeEventListener();
  _eventListener();
}

같은 일을 하는 함수인데, 이렇게 보면 이벤트리스너 안에 있는 function () 의 클로저가 어떻게 생기고

비공개변수를 스코프에 가지고 간다는 것을 좀더 명확하게 볼 수 있다.

+ Recent posts