Closures

조양권·2021년 5월 18일
0

JS

목록 보기
7/17

저번의 스코프(Scope)에 이어 오늘은 클로져(Closures)에 대해 알아보겠다.

클로져(Closures)

클로져란 내부함수가 외부함수의 맥락(context)에 접근할 수 있음을 의미한다. 외부함수는 외부함수의 지역변수를 사용하는 내부함수가 소멸될때 까지 소멸되지 않는 특성을 의미한다.

내부함수가 외부함수에 접근

function outter_fn(){
let printing = 'im outter'
 function inner_fn(){  
  console.log(printing)
 }
inner_fn();
}
outter_fn(); // 'im outter'

위의 코드를 보면 inner_fn안에는 printing이라는 변수가 없지만 외부함수(여기서는 outter_fn)에 접근하여 printing이라는 변수를 성공적으로 출력함을 볼 수 있다.

외부함수가 소멸되지 않음

정확히는 외부함수는 외부함수의 맥락을 이용하는 내부함수가 종료될때까지 외부함수는 소멸되지 않는다. 이는 JS의 구동방식을 이해했다면 조금 낯설 수 있는 개념이다.

function outter_fn(){
let printing = 'im outter'
 return function(){  
  console.log(printing)
 }
}
inner_fn = outter_fn()
inner_fn(); // 'im outter'

위의 함수를 일반적인 작동방식으로 생각해보면,

  1. outter_fn()이 호출된다.

  2. 그 결과로 inner_fn에 이름없는 함수(console.log를 수행하는)가 담긴다.

  3. 위의 과정을 거치고 outter_fn()의 함수는 종료됬으므로 이 함수의 지역변수는 소멸되는 것이 맞다.(printing)

  4. 하지만 출력결과는 정상적으로 printing이 undefined가 아님을 보여주고 있다.

이렇게 외부함수가 소멸되지 않음을 closures의 특징으로 볼 수 있다. 내부함수 (이름없는 함수)는 외부함수 outter_fn의 맥락(지역변수)에 접근하고 있는 함수이다. outter_fn,외부함수가 종료된 것 처럼 보이지만 아직 외부함수의 맥락에 접근하고 있는 내부함수가 종료되지 않았으므로 정상적으로 외부함수의 맥락인 printing에 접근할 수 있었던 것이다.

클로져의 특징

그렇다면 이러한 클로져는 왜 사용하는 것일까.

클로져는 단독으로 호출되어도 외부함수의 정보와 연결되어 있기 때문에 값들이 동적으로 변환되어도 반영된다는 장점이 있다. 또한 전역변수의 남용을 막을 수 있고 변수값을 은닉하는 용도로 사용할 수 있다.(private)

// HTML
<button onclick='print()'>버튼</button>
// JS
let click = (function (){
 //클릭한 수를 카운팅
 let count = 0
 return function(){
  count ++
  return count
 }
})()
function print(){
 console.log(click())
}

위의 함수는 변경된 count값이 정상적으로 반영된다. print함수 안에 있는 click함수는 이름없는 함수(클로져)를 반환하고 호출한다. 클로져는 click함수의 count를 계속 기억하고 있으므로 변경된 count가 정상적으로 반영이 된다.

또한 count변수를 전역변수에 선언하지 않고 click안에 숨김으로서 count라는 변수가 다른 곳에서 오남용 되는 일을 막을 수 있다. 이는 코드의 규모가 복잡하고 커질수록 굉장히 중요한 장점으로 부각된다.

profile
할 수 있는 것이 늘어나는 즐거움

0개의 댓글