Frontend-dev/HTML-CSS-JS
자바스크립트 클로저(closure)
RunningWater
2018. 2. 27. 02:26
클로저란?
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는 아주 자주 보이니 꼭 충분한 연습을 하시는 게 좋습니다.
공감은 제작자에게 큰 힘이 됩니다.