자바스크립트 - 클로저란? (closure)

반응형

클로저란?

클로저는 영어로는 closure 폐쇄라는 뜻을 가지고 있습니다.

자바스크립트에서 클로저는 이렇게 정의할 수 있습니다.

 

클로저는 자신(함수)이 생성될 때, 자신의 스코프에서 알 수 있는 변수를 기억하는 함수입니다.

 

클로저 예시

function a() {
  var num1 = 5;
  function b(num2) {
    return num1 + num2;
  }
  return b;
}

var obj = a();
console.log(obj(5)); // 10
console.log(obj(10)); // 15

 

b 함수가 클로저입니다.

b 함수가 생성될 때, num1 변수를 기억하고 있고,

a 함수의 실행이 끝나도, obj 함수를 통해서 계속 num1 값을 기억하여 새로운 값을 만들 수 있습니다.

 

 

클로저는 언제 사용해야 할까?

그래서 클로저는 언제 사용해야 할까?

처음 자바스크립트를 공부할 때, 정보 보호 또는 은닉을 위해서 사용한다고 공부를 했던 기억이 있습니다.

틀린 말은 아니지만, 이런 상황에서 사용하면 좋습니다.

  1. 이전 상황을 나중에 일어날 상황과 이어나갈 때,
  2. 함수로 함수를 만들거나 부분 적용을 할 때

클로저 실제 사용 예시

var array = [
  { name: 'superman', text: '안녕하세요'},
  { name: 'batman', text: '반갑습니다'},
  { name: 'pororo', text: '수고하셨습니다.'},
]

for (let i = 0; i < array.length; i++) {
  var button = document.createElement('button');
  var item = array[i];
  button.innerHTML = item.name
  
  button.addEventListener('click', function() {
    alert(item.text + ' ' + item.name);
    
  })
  div.append(button);
}

 

위와 같은 배열로 버튼을 만들 때, for문을 이용해서 반복문으로 3개의 버튼을 만들어서 클릭 이벤트를 적용하게 되면

모든 클릭 이벤트에서 마지막 배열의 값이 이벤트에 발생하게 됩니다.

 

이러한 문제점들을 클로저를 통해서 해결할 수 있습니다.

for (let i = 0; i < array.length; i++) {
  var button = document.createElement('button');
  var item = array[i];
  button.innerHTML = item.name;
  
  (function(_item) {
     button.addEventListener('click', function() {
      alert(_item.text + ' ' + _item.name);
     });
  })(item);

  div.append(button);
}

 

함수 실행 시 전달받은 item을 클로저 함수에서 _item으로 보존하여 사용할 수 있습니다.

 

 

그 외에도 변수를 const로 할당하거나, forEach를 이용해서 해결할 수 도 있습니다.

 

728x90
반응형