티스토리 뷰

클로저란?

MDN에서는 클로저를 "함수와 함수가 선언된 어휘적 환경의 조합이다."라고 적혀있습니다. 조금 더 풀어서 얘기해볼까요? 저번 포스팅에 스코프에서 대해서 다뤘습니다. 자바스크립트는 정적(Lexical)스코프를 가지고 있었습니다. 선언될 때 자기가 접근할 수 있는 스코프가 정해졌었습니다. 그리고 블록의 내부에서는 블록의 외부로 접근할 수 있었지만 외부에서는 내부로 접근할 수 없었습니다. 이러한 환경들이 합쳐 클로저(closure)가 만들어집니다.

function outer(){
  const name="lemonCandy";
  function inner(){
    console.log(name);
  }
  return inner
};
const func = outer();


outer라는 함수 내부에 name이라는 지역변수가 있고, 그 값에 접근할 수 있는 inner라는 함수가 있습니다. 그리고 outer는 그 함수를 반환합니다. outer를 실행하면 func에는 outer의 리턴값이 담기겠죠? 그리고 func()를 실행하면 콘솔창에 lemonCandy라는 글씨가 적혀있는 것을 볼 수 있습니다. 변수에 직접 접근할 수는 없게 클로저(닫다, 좁히다)시키고 여전히 활용하는 겁니다. 

클로저로 프라이빗 함수와 변수 만들기

위의 예제를 좀 더 변화시켜볼까요? 창작자에게 힘이 되는 좋아요 함수를 만들어 보겠습니다.

function likeCounter(){
  let like = 0;
  function changeBy(val){
    like += val;
  }
  return {
  iLike: function(){
      changeBy(1);
    },
  disLike: function(){
      changeBy(-1);
    },
  checking: function(){
      return like;
    }
  }
};
const Like = likeCounter();


likeCounter 함수엔 like라는 변수와 changeBy라는 like 값을 바꿀수 있는 함수가 있습니다. 그리고 iLike, disLike, checking이라는 메소드를 가진 객체를 반환합니다. 맨 밑줄에서는 Like라는 상수에 리턴 값이 담기죠.


Like.iLike(); // like === 1
Like.iLike(); // like === 2
Like.iLike(); // like === 3
Like.checking(); // 3
Like.disLike(); //like === 2


메소드들을 통해서 like의 값을 증감시킬 수 있습니다. 중요한건 함수 외부에서는 like나 changeBy 함수에 직접 접근할 수 없고, 반환한 객체의 메소드들을 통해서만 값을 증감시킬 수 있다는 것입니다. 이렇게 클로저를 사용하는 것을 모듈패턴이라고 합니다. 클로저에 대해서 조금 이해가 되셨나요?

즉시실행함수(IIFE)

클로저와 함께 즉시실행함수를 알아봅시다. Immediately-invoked function expression을 줄여서 IIFE라고 합니다. 다시 사용할 때 함수는 아주 편리합니다. 이름을 짓고 괄호만 붙이면 여러번 다시 사용할 수 있으니까요. 그러나 한번만 쓰면 될 경우엔 이름 자체가 아주 귀찮아지고 무의미해집니다. 그래서 함수를 정의하고 바로 실행시켜버리는 것입니다.

(function(name){
  console.log("hello " + name);
  console.log("candy world");
})("lemon");


위의 소스코드처럼 익명함수를 정의하고 함수부분을 괄호로 감싼 뒤에 바로 실행시키면 됩니다. 사용했던 예제를 즉시실행함수를 통해 좀더 편하게 바꿔보겠습니다. 


const Like = (function(){
  let like = 0;
  function changeBy(val){
    like += val;
  }
  return {
  iLike: function(){
      changeBy(1);
    },
  disLike: function(){
      changeBy(-1);
    },
  checking: function(){
      return like;
    }
  }
})();


좀더 간단하게 코드가 적힌게 보이시나요? 즉시실행되서 Like에 담기고, 아까처럼 사용하시면 됩니다.



클로저와 IIFE는 아주 자주 보이니 꼭 충분한 연습을 하시는 게 좋습니다.



공감은 제작자에게 큰 힘이 됩니다. 


댓글