문서내의 모든 버튼을 클릭했을때,
각각 "btn-0 클릭", "btn-1 클릭", "btn-2 클릭"
... "btn-n 클릭"을 콘솔에 출력하시오.
<script>
window.onload = function () {
const btns = document.querySelectorAll("button");
// IIFE pattern
for (var i = 0; i < btns.length; i++) {
btns[i].addEventListener("click", function () {
console.log(`btn-${num}클릭`);
});
}
};
</script>
위의 그림에서 알수 있듯이 var을 사용하면 원하는 결과를 얻을 수 없다.
i = 0일 때, function() { console.log(i); } 함수를 배열에 저장.
i = 1일 때도 또 함수 저장.
i = 2일 때도 또 함수 저장.
그래서 funcs에는 함수가 3개 저장:
[
function() { console.log(i); },
function() { console.log(i); },
function() { console.log(i); }
]
이 세 함수는 모두 같은 i를 바라보고 있다! (어매나)
현재 위 코드에서 i는 모든 함수들이 같이 보는 공용 메모장 같은 것
반복문은 메모장에 숫자 적으면서 함수들을 저장해두는 거고,
함수들은 "나중에 저 메모장에 적힌 거 보고 출력할게!" 라고 약속해놓은 상황.
근데 반복문이 끝나고 나면, 메모장에는 3만 써 있음.(var라는 놈이 이래서 문제다,,)
그래서 함수들이 실행될 때마다 3만 출력
<script>
window.onload = function () {
// 문서내의 모든 버튼을 클릭했을때
// 각각 "btn-0 클릭", "btn-1 클릭", "btn-2 클릭"
// ... "btn-n 클릭"을 콘솔에 출력하시오.
const btns = document.querySelectorAll("button");
// IIFE pattern
for (var i = 0; i < btns.length; i++) {
((num) => {
btns[i].addEventListener("click", function () {
console.log(`btn-${num}클릭`);
});
})(i);
}
};
</script>
이런 방식으로 해결할 수 있다.
하지만 지금은 2025년.
우리는 let과 forEach를 사용함으로써 이를 해결할 수 있다.
// ECMA5 forEach
// Array.prototype.forEach: 배열의 각 요소를 순회하면서 지정한 콜백 함수를 실행
// 콜백 함수는 첫번째 인자로 배열의 요소, 두번째 인자로 요소의 인덱스를 전달받는다.
// [btn1, btn2, btn3].forEach((btn, i) => { });
btns.forEach(function(btn, i){
btn.addEventListener('click', function(){
console.log(`btn-${i} 클릭`);
});
});
// ECMA6 let
for(let i=0; i<btns.length; i++){
btns[i].addEventListener('click', function(){
console.log(`btn-${i} 클릭`);
});
}