Post

이벤트를 등록하는 방식, 이벤트 핸들러 내부의 this

이벤트 핸들러 attribute 방식

1
2
3
4
5
6
<button onclick="handleClick()">Click me</button>
<script>
  function handleClick() {
    console.log(this); // window
  }
</script>

위 예제의 handleClick 함수 내부의 this는 전역 객체 window를 가리킨다.

일반 함수 내부의 this는 전역 객체를 가리키기 때문이다.

단, 이벤트 핸들러를 호출할 때 this를 인수로 전달하면 이벤트를 바인딩한 DOM 요소를 가리킨다.

1
2
3
4
5
6
7
<button onclick="handleClick(this)">Click me</button>
<script>
  function handleClick(button) {
    console.log(button); // 이벤트를 바인딩한 button 요소
    console.log(this); // window
  }
</script>

addEventListener 방식

addEventListener 핸들러 내부의 this는 이벤트를 바인딩한 DOM 요소를 가리킨다.

1
2
3
4
5
6
7
8
<button id="el">클릭해라</button>
<script>
  const button = document.getElementById("el");

  button.addEventListener("click", function () {
    console.log(this); // 이벤트를 바인딩한 button 요소
  });
</script>

arrow function으로 정의한 이벤트 핸들러 내부의 this는 상위 스코프의 this를 가리킨다.

arrow function은 함수 자체의 this 바인딩을 갖지 않는다.

1
2
3
4
5
6
7
8
<button id="el">클릭해라</button>
<script>
  const button = document.getElementById("el");

  button.addEventListener("click", () => {
    console.log(this); // window
  });
</script>

이 경우에는 e.currentTarget을 통해 button 요소에 접근할 수 있다.

1
2
3
4
5
6
7
8
9
10
11
12
<button id="el">클릭해라</button>
<script>
  const button = document.getElementById("el");

  function handleClick() {
    console.log("handleClick", this);
  }

  button.addEventListener("click", (e) => {
    console.log(e.currentTarget); // button 요소
  });
</script>

두 방식의 차이점

  • addEventListener는 하위 버전의 브라우저에서 지원하지 않는다.

  • attribute 방식으로는 하나의 콜백 함수(리스너)만 지정할 수 있지만, addEventListener는 여러 개의 이벤트 리스너를 추가할 수 있다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
<div id="div1">Click me!</div>
<script>
  document.getElementById("div1").onclick = function (e) {
    alert("do process #1");
  };
  document.getElementById("div1").onclick = function (e) {
    alert("do process #2");
  };
</script>
<!-- 위 코드의 경우 #2만 출력된다. -->

<div id="div2">Click me!</div>
<script>
  document.getElementById("div2").addEventListener("click", function (e) {
    alert("do process #1");
  });
  document.getElementById("div2").addEventListener("click", function (e) {
    alert("do process #2");
  });
</script>
<!-- 위 코드의 경우 #1과 #2 모두 출력된다. -->
  • JavaScript 모듈 또는 다른 라이브러리와 확장이 용이하기 때문에 모질라 등 개발자 포럼에서 addEventListener 사용을 더 추천하고 있다!

참고사이트

모던 자바스크립트 Deep Dive - 789p
[js] 자바스크립트 onclick · addEventListener 비교 사용법
[자바스크립트] 이벤트 핸들러(리스너) 등록과 addEventListener/attachEvent vs onload 차이점

This post is licensed under CC BY 4.0 by the author.