자바스크립트 입문_콜백함수 내부에서 외부 데이터를 사용하고자 할때
자바스크립트 2021. 5. 9. 13:56(본 포스팅은 위키북스의 '코어자바스크립트' 책을 공부하면서 작성되었습니다_내돈내산)
- 이벤트 리스너에 관한 클로저 예시(1) -
let fruits = ['apple', 'banana', 'peach'];
let $ul = document.createElement('ul');
fruits.forEach(function(fruit){
let $li = document.createElement('li');
$li.innerText = fruit;
$li.addEventListener('click', function(){
alert('your choice is ' + fruit); // 클로저
});
$ul.appendChild($li);
});
- forEach의 콜백함수가 addEventListener를 이용할때 외부의 변수를 참조하게 됨.
- 이벤트 리스너에 관한 클로저 예시(2) : bind사용-
let fruits = ['apple', 'banana', 'peach'];
let $ul = document.createElement('ul');
let alertFruit = function(fruit) {
alert('your choice is ' + fruit);
};
fruits.forEach(function(fruit){
let $li = document.createElement('li');
$li.innerText = fruit;
$li.addEventListener('click', alertFruit); // [object MouseEvent] 출력
$ul.appendChild($li);
});
document.body.appendChild($ul);
alertFruit(fruits[1])
- 위의 코드는 맨 마지막줄 코드는 'banana'에 대한 alert구문이 정상적으로 실행되지만 addEventListener의 경우 'li' 태그를 클릭했을때 [object MouseEvent]라는 값이 출력됨.
- 이는 콜백함수의 제어권을 addEventListener가 가진 상태이며, 이는 콜백함수를 호출할 때 첫번째 인자에 '이벤트 객체'를 주입하기 때문. 이 문제를 bind를 이용해 해결이 가능함.
let fruits = ['apple', 'banana', 'peach'];
let $ul = document.createElement('ul');
let alertFruit = function(fruit) {
alert('your choice is ' + fruit);
};
fruits.forEach(function(fruit){
let $li = document.createElement('li');
$li.innerText = fruit;
$li.addEventListener('click', alertFruit.bind(null, fruit)); // bind 사용
$ul.appendChild($li);
});
document.body.appendChild($ul);
alertFruit(fruits[1])
- 위와같은 방법으로 해결이 가능하지만 이렇게 하는 경우,
- 이벤트 객체가 인자로 넘어오는 순서가 바뀌는 점.
- 함수 내부에서의 this가 원래의 그것과 달라지는 점.
두가지의 감안이 필요함. - 이런 변경사항이 발생하지 않게 '고차함수'를 활용할 수 있음.
...
let alertFruitBuilder = function(fruit){
return function() {
alert('your choice is ' + fruit);
};
};
fruits.forEach(function(fruit){
let $li = document.createElement('li');
$li.innerText = fruit;
$li.addEventListener('click', alertFruitBuilder(fruit));
$ul.appendChild($li);
});
...
- 위에서 사용했던 alertFruit 함수 대신에 alertFruitBuilder 라는 함수를 작성하였음.
- 이 함수 내부에서는 기존의 alertFruit였던 함수를 반환하게 됨.
- forEach문의 addEventListener안의 alertFruitBuilder 콜백 함수를 실행하면서 외부변수인 fruit를 outerEnvironmentReference에 의해 참조하게 됨. 즉 alertFruitBuilder의 실행결과로 반환된 함수에는 클로저가 존재하게 됨.
'자바스크립트' 카테고리의 다른 글
자바스크립트 입문_부분적용함수 구현 (0) | 2021.05.09 |
---|---|
자바스크립트 입문_접근권한제어(정보은닉) (0) | 2021.05.09 |
자바스크립트 입문_클로저와 메모리 관리 (0) | 2021.05.09 |
자바스크립트 입문_클로저의 의미 및 원리 (0) | 2021.05.08 |
자바스크립트 입문_콜백지옥(callback hell), 비동기(async) 제어 (0) | 2021.05.08 |