이벤트 처리, 반복문, 콜백함수

Suxxzzy.log·2021년 12월 10일
0

에러핸들링

목록 보기
5/32

section1 문제를 풀면서 마주했던 내용이었다.

const arr = ['dog' , 'cat']
const ul = document.querySelector('ul')

for(let i = 0 ; i < arr.length ; i++){
  const li = document.createElement('li')
  const span = document.createElement('span')
  li.textContent = arr[i];
  span.textContent = `I like ${arr[i]}s`;
  ul.append(li,span);
  
  li.addEventListener('click', console.log(`${arr[i]}`))
}

이와 같이 코드를 작성하고 당연히 될거라고 생각했지만, 테스트 통과가 되지않았다.
vscode를 켜서 브라우저에서 확인해 봤는데,
클릭을 할 때마다 콘솔에는 undefined가 뜨고 있었다.

인터넷을 검색해보니 나와 비슷한 문제를 겪었던 선례들이 정말 많이 있었다.
그런데 그 코드들은 모두 변수를 var로 선언을 했었고, 스택오버플로우에는 답변자가 var는 스코프를 무시하기 때문에, 변수에 할당된 이전의 값들이 모두 사라진다고 했다. 그래서 var보다는 let을 사용하는 것이 좋다고 했다.
var는 배운대로 블록스코프를 무시하고, 밖에 있는 변수에 접근하기 때문에 항상 마지막 값을 가리킨다고 한다
그러면 let을 쓰면 된다는 건데.
let은 선언할 때마다 각각의 스코프가 생기기 때문에 var 처럼 클로저가 생기는 문제는 걱정을 안해도 된다고 했다. 그러면 지금 변수는 맞게 쓴 거잖아.

문제는 이벤트핸들러에 사용하는 콜백함수였다.
내가 전날에 리액트 문제를 풀지 못했던 이유와 동일했다.
함수 자체를 전달해야 하는데, 함수에 인자를 넣어 호출한 값을 전달했기 때문에, 브라우저를 실행하자마자 함수도 같이 실행이 된 것이다.
즉 내가 클릭을 할 때만 실행이 되어야 하는데, 이미 실행된 값이 들어간 것이니, 클릭을 해도 콘솔에는 undefined가 뜨는 것이었다.
따라서 코드는 다음과 같이 수정되어야 한다.

const arr = ['dog' , 'cat']
const ul = document.querySelector('ul')

for(let i = 0 ; i < arr.length ; i++){
  const li = document.createElement('li')
  const span = document.createElement('span')
  li.textContent = arr[i];
  span.textContent = `I like ${arr[i]}s`;
  ul.append(li,span);
  
  li.addEventListener('click', () => console.log(`${arr[i]}`))
}

항상 놓치고 가는 부분인데, 클로저보다 이게 더 중요한 내용이었다.
그치만 클로저에 대한 내용도 짚어보고 갈 수 있어서 (변수를 var로 선언해둔걸완전히 이해한 건 아니지만?..ㅠ) 좋았다고 생각한다.

profile
몫을 다하는 사람

0개의 댓글