JavaScript에서 클릭 핸들러에 객체 메서드 바인딩하기
JavaScript에서 이벤트 핸들러를 다룰 때 가장 흔히 겪는 문제 중 하나는 this 참조입니다. 객체의 메서드를 이벤트 핸들러에 직접 전달하면, 핸들러 내부의 this는 해당 객체가 아닌 이벤트가 발생한 DOM 요소를 가리키게 되어 의도대로 동작하지 않습니다.
이 문제를 해결하는 가장 간단한 방법은 화살표 함수(arrow function) 안에서 객체의 메서드를 호출하는 것입니다. 화살표 함수는 자신만의 this를 생성하지 않으므로, 객체의 컨텍스트가 그대로 유지됩니다.
다음은 객체의 메서드를 클릭 핸들러에 바인딩하는 JavaScript 코드입니다.
예제
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
<style>
body {
font-family: "Segoe UI", Tahoma, Geneva, Verdana, sans-serif;
}
.result {
font-size: 20px;
font-weight: 500;
color: blueviolet;
}
</style>
</head>
<body>
<h1>Binding an object's method to a click handler in JavaScript</h1>
<div class="result"></div>
<br />
<button class="Btn">Click Here</button>
<h3>Click on the above button to know how many times you have clicked the button</h3>
<script>
let resEle = document.querySelector(".result");
let BtnEle = document.querySelector(".Btn");
let testObj = {
a: 0,
timesClicked() {
this.a += 1;
resEle.innerHTML = "Times clicked = " + this.a;
},
};
BtnEle.addEventListener("click", () => {
testObj.timesClicked();
});
</script>
</body>
</html>실행 결과
위 코드를 실행하면 다음과 같은 화면이 나타납니다.

'Click Here' 버튼을 클릭하면 버튼을 누른 횟수가 아래와 같이 화면에 표시됩니다.

동작 원리 살펴보기
예제 코드의 핵심 부분은 다음과 같습니다.
let testObj = {
a: 0,
timesClicked() {
this.a += 1;
resEle.innerHTML = "Times clicked = " + this.a;
},
};
BtnEle.addEventListener("click", () => {
testObj.timesClicked();
});testObj객체는 클릭 횟수를 저장할 속성a와, 클릭될 때마다 값을 1씩 증가시키고 화면에 출력하는timesClicked()메서드를 가지고 있습니다.addEventListener에 등록된 콜백이 일반 함수였다면this가 버튼 요소를 가리켜 오류가 발생할 수 있습니다.- 화살표 함수로 감싸서
testObj.timesClicked()를 호출했기 때문에, 메서드 내부의this는 항상testObj를 올바르게 가리킵니다.
다른 바인딩 방법
화살표 함수 외에도 다음과 같은 방법으로 메서드를 바인딩할 수 있습니다.
- bind() 메서드:
BtnEle.addEventListener("click", testObj.timesClicked.bind(testObj));처럼bind()를 사용해this를 명시적으로 고정할 수 있습니다. - 일반 함수 래퍼:
function() { testObj.timesClicked(); }형태의 익명 함수로 감싸 호출하는 방법도 동일하게 동작합니다.
상황에 따라 적절한 방법을 선택하면, 이벤트 핸들러에서도 객체의 상태를 안전하게 관리할 수 있습니다.