본문 바로가기
JavaScript

클로저 활용 예시 (1)

by whoyoung90 2022. 3. 31.
반응형

클로저 활용 예시 (1) - 콜백함수가 외부 데이터 참조

 

콜백함수 내부에서 외부변수를 참조하는 클로저의 두가지 로직을 기록하기 위해🧐

 

첫 번째는 콜백함수를 내부함수로 선언해서 외부변수를 직접 참조하는 로직이고,

두 번째는 콜백함수를 고차함수로 바꿔서 클로저를 활용하는 로직이다.

 

1.  콜백함수가 외부변수를 직접 참조

let delivery = ['chicken', 'pizza', 'sushi'];
let $ul = document.createElement('ul');

delivery.forEach(el => { // 콜백함수(A)
  let $li = document.createElement('li');
  $li.innerText = el;
  $li.addEventListener('click', function() { // 콜백함수(B)
    alert('오늘의 저녁은 ' + el);
  });
  $ul.appendChild($li);
});
document.body.appendChild($ul);

콜백함수 A는 내부에서 외부 변수를 사용하지 않고 있으므로 클로저가 없지만
콜백함수 B는 el이라는 외부 변수를 참조하고 있으므로 클로저가 있다.

 

A의 실행 종료 여부와 무관하게, 클릭 이벤트에 의해 B가 실행된다면
최소한 B가 참조할 예정인 변수 el에 대해서는 A가 종료된 후에도 계속 참조가 가능하다! (가비지 컬렉터 대상 제외)

 

1-1.  ❌ 콜백함수 B를 외부로 분리한다면?

[object MouseEvent] 출력

콜백함수를 외부로 분리하는건 좋은 시도지만, 이 코드대로 li를 클릭하면

음식명이 아닌 [object MouseEvent]가 출력된다.

 

콜백함수의 인자에 대한 제어권을 addEventListener가 가진 상태이며

addEventListener는 콜백함수를 호출할 때 첫번째 인자에 '이벤트 객체'를 주입하기 때문!

 

2.  고차함수를 활용하여 해결

고차함수란? 함수를 인자로 받거나 함수를 리턴하는 함수

let delivery = ['chicken', 'pizza', 'meat'];
let $ul = document.createElement('ul');

/* 고차함수 */
let highFunc = function(el) {
  return function() {
    alert('오늘의 주문은 ' + el); // 익명함수를 반환
  }
};
delivery.forEach(el => {
  let $li = document.createElement('li');
  $li.innerText = el;
  $li.addEventListener('click', highFunc(el)); // highFunc(el)
  $ul.appendChild($li);
});
document.body.appendChild($ul);
highFunc(delivery[2]);

/* 클릭 이벤트 발생시 익명함수를 호출 (클로저) */

고차함수 highFunc의 내부에서 다시 "익명함수를 반환"한다.

 

고차함수의 실행 결과가 다시 함수가 되며, "이렇게 반환된 함수"를 addEventListener의 콜백함수로 전달한다.

 

이후 클릭 이벤트가 발생하면 비로소 익명함수가 호출되고 highFunc의 인자로 넘어온 el을 참조한다!

 

즉, highFunc의 실행결과로 반환된 함수에는 클로저가 존재한다.

 

 

반응형

'JavaScript' 카테고리의 다른 글

커링 함수  (0) 2022.05.21
클로저 활용 예시 (2)  (0) 2022.05.01
setInterval과 addEventListener  (0) 2022.03.31
클로저 (Closure)  (0) 2022.03.30
콜백 함수도 함수로서 호출이다  (1) 2022.02.26

댓글