ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 자바스크립트(javascript) 클로저
    카테고리 없음 2023. 4. 20. 09:53
    자바스크립트의 클로저에 대해 알아보자. 자바스크립트를 완전 복잡하게 다루지 않는다면 몰라도 되고 알아도 되는 내용? 인가? 알아두면 좋긴하지.. 클로저를 알아보기전에 잠깐 알아야 될 것이 있다. 자바스크립트의 내부함수와 외부함수의 개념이다. 의미 자체는 간단하다. 내부함수는 함수 함수안에 함수가 있는 것이고 외부함수는 내부함수를 갖고 있는 함수를 외부함수라 한다. 간단하게 코드로 보자.
    function outterFunction(){
      var outterNum = 10;
      function innerFunction(num){
        return num + outterNum;
      }
      return innerFunction;
    }
    var outter = outterFunction();
    alert(outter(10));
    alert(outter(3));
    
    딱히 보기엔 정말 간단한 코드이다. 여기서 outterFunction는 외부함수를 말하고 그 안에 있는 innerFunction이 내부 함수를 말하는 것이다. 어렵지 않다. 근데 가만보면 outterNum이라는 변수는 외부함수의 지역변수이지만 내부함수 innerFunction은 outterNum에 접근할 수 있다. 이것을 바로 클로저라 한다. 외부함수가 더이상 사용 되지 않는 경우에도 내부함수가 외부함수의 접근할 수 있다는 이야기다. 위의 코드는 아래와 같이도 할 수 있다.
    function outterFunction(){
      var outterNum = 10;
      return function(num){
        return num + outterNum;
      }
    }
    var outter = outterFunction();
    alert(outter(10));
    alert(outter(3));
    
    근데 가만보면 조금 이상한 코드이다. 물론 오히려 자바스크립트를 처음하는 사람에겐 그냥 그러려니하지만 프로그래밍을 어느정도 한 사람에게는 조금 이상하다. 외부함수는 다른(내부) 함수를 리턴하고 있다. 함수가 리턴되면 그 함수는 종료되었다는 것이다. outterFunction()을 호출하고 outterFunction 함수가 생을 마감하였지만 outter(10)을 호출하여도 제대로 동작을 한다. outter(10)은 내부함수를 호출하는 것이다. 내부함수에는 outterNum 변수가 존재 하지 않는대도 외부함수의 outterNum을 접근할 수 있다는 이야기다. 그럼 어느때에 이런 클로저를 쓰는지 보자. 예를들어 이런 html코드가 있다고 가정하자
      <ul>
        <li>li1</li>
        <li>li2</li>
        <li>li3</li>
        <li>li4</li>
        <li>li5</li>
      </ul>
    
    아주 간단하게 ul태그안에 li태그가 5개 존재하는 html 코드이다. 우리는 li를 클릭했을때 자신이 위취한 번째를 console로 출력해는 그런 코드를 작성하려고 한다. 그래서 이렇게 작성하였다.
    window.onload = function() {
      var items = document.getElementsByTagName("li");
      for(var i=0; i < items.length; i++) {
        items[i].onclick = function() {
           console.log(i + 1);
        }
      }
    }
    
    딱보면 나쁘지 않는 코드이다. li태그를 찾아서 n개의 이벤트를 등록시켰다. 그리고 나서 실행을 시켜보았다. 하지만 결과는 완전 이상하다. 어느 것을 클릭을 해도 하나의 숫자만 나온다. 지금 이코드에서는 6이라는 것만 출력된다. 무엇이 잘못되었나. 실제 for문이 종료 되는 시점은 5이고 핸들러가 그것을 접근하여 1을 더한 값만을 출력하는 것이다. 그래서 모든 li를 클릭을 했을때는 6이 나오는 것이다. 그럼 제대로 동작하게 고쳐보자.
    window.onload = function() {
      var items = document.getElementsByTagName("li");
      for(var i=0; i < items.length; i++) {
        (function(m){
            items[i].onclick = function() {
              console.log(m + 1);
          }
        })(i);
      }
    }
    
    우리는 내부에 익명함수를 만들어 파라미터를 넘겨서 실행 시켰다. 원래는 구조상 실행뒤에 생을 마감해야 하지만 클로저로 인해 할당된 변수를 각각의 이벤트에 넣어 사용할 수 있게 되었다. 이렇게해서 우리가 원하는 결과를 얻을 수 있게 되었다. 예전에 다음맵을 사용할 때 기억이 나는 듯하다. 여러 이벤트를 등록 할 때 클로저로 해야 원하는 결과를 얻을 수 한거 같다. 자바스크립트는 완전 잘 몰라서 클로저도 대충 이해만 했다. 자바스크립트도 잘하는 분이 많으니.. 한마디로 클로저란 함수의 생명을 마감하였지만 내부 함수가 외부함수의 변수들을 참조하고 있기때문에 접근가능할 것을 클로저라한다. 스코프(범위)와 많은 관련이 있는 것이다. 이상으로 클로저에 대해 살짝 알아봤다!.

    댓글

Designed by Tistory.