함수 선언문으로 작성했을 때 document가 나오는 이유는 click 이벤트가 발생하면 addEventListener() 메서드가 콜백 함수의 this를 event.target으로 바꿔서 호출하기 때문입니다. 그래서 addEventListener() 메서드 안에서 함수 선언문을 사용하면 document가 출력되고, 화살표 함수를 사용하면 window가 출력됩니다.
이벤트 리스너는 대표적인 비동기 함수 중 하나라서 이벤트 리스너의 동작을 설명하려면 호출 스택과 이벤트 루프, 백그라운드, 태스크 큐가 등장할 수밖에 없습니다.
앞의 코드에서 addEventListener() 메서드를 실행하는 순간 백그라운드에는 이벤트 리스너가 등록됩니다. 백그라운드와 태스크 큐를 설명할 때 호출 스택뿐만 아니라 백그라운드와 태스크 큐까지 비어 있어야 전체 코드가 종료된다고 했죠? 이벤트 리스너는 타이머와 다르게 일정 시간 뒤에도 백그라운드에서 지워지지 않습니다. 즉, 이벤트 리스너가 존재하는 동안에는 전체 코드도 종료되지 않습니다. 그래서 언제나 준비하고 있다가 click 이벤트가 발생하는 순간 이벤트 리스너의 콜백 함수를 태스크 큐로 보냅니다.