자바스크립트에서 this
는 기본적으로 전역객체(window)
에 바인딩 된다.
하지만 함수를 어떻게 호출하느냐에 따라 this의 값은 달라지는데 이에 대한 내용은
다음 글을 참고하면 된다.
자바스크립트 이벤트핸들러에서 this
가 가리키는 객체는 호출 방식과 관련이 있다.
이벤트 핸들러는 다음과 같은 방법으로 호출될 수 있다.
HTML 요소에 직접 이벤트 핸들러를 설정하는 방법이다.
이때 this
는 해당 요소를 가리킨다.
자바스크립트에서 this
는 함수 호출 방식에 따라 다르게 결정되는데,
그렇다면 아래 코드는 window 전역객체
가 나와야 하지만 해당 요소가 출력된다.
<button onClick={console.log(this)}>btn</button>
이번엔 printThis()
를 선언해서 HTML요소 이벤트 핸들러 attribute의 값으로 함수를 넣어서 실행해 주었다. 그때 this
의 값은 다음과 같다.
<button onClick="printThis()">btn</button>
function printThis () {
console.log(this);
};
인라인으로 HTML요소에 onClick Attribute방식은 어째서 다르게 동작할까?
onClick="printThis()"
attribute는 다음과 같이 표현될 수 있다.
<button id="btn" onClick="printThis()">btn</button>
function printThis() {
console.log(this);
};
function onclick(){ // onClick attribute 이름과 같은 함수가 생성
printThis();
};
// 동일한 이름인 onclick에 암묵적으로 생성된 onClick함수를 할당
document.getElementById('btn').onClick = onClick;
이벤트 핸들러에 등록된 함수는 printThis()가 아닌 암묵적으로 생성된 onClick함수이다.
onClick함수 안에서 printThis함수는 일반함수로 호출되어 printThis함수 내부의 this
는 전역객체(window)
가 된다.
addEventListener
메서드를 사용해서 이벤트 핸들러를 등록하는 방법이다.
addEventListener
메서드 내 일반함수를 사용하는 방법이다.
document.getElementById("btn").addEventListener('click', function(){
console.log(this);
});
이때 this
는 이벤트를 발생시킨 요소를 가리킨다.
화살표 함수를 사용해서 이벤트 핸들러를 작성하는 방법이다.
document.getElementById("btn").addEventListener('click', ()=>{
console.log(this);
});
이때 this
는 이벤트 핸들러를 정의한 컨텍스트를 가리킨다.
화살표 함수로 정의되었기 때문에 this
가 해당 요소를 가리키지않고, 메서드가 정의된 컨텍스트(즉, 전역객체 window
)를 가리킨다.
여러 요소가 있고, 모두 같은 이벤트 핸들러가 등록되었다면 그 이벤트가 발생하면 해당 요소를 참조하는게 편할 것이다.
이벤트 핸들러의 this는 이벤트 객체의 currentTarget속성과 같다.
다만, 화살표 함수는 스스로 this를 갖지 못한다는 점을 기억해야 한다.
이처럼 이벤트 핸들러 내부의 this는 이벤트를 바인딩하는 DOM 요소를 가리킨다.
참고
안녕하세요, 고경호 님.
저는 출판사 비제이퍼블릭의 기획편집 담당자 최규리라고 합니다.
선생님의 벨로그를 살펴보고 도시 출간을 제안드리고자 메일드립니다. 😊
능력을 쌓는 것뿐만 아니라, 기술의 원리까지 세밀하게 파악하시고
습득하는 기술에 대해 꼼꼼하게 정리하고 계신 경호 님께서
블로그 게시글을 차곡차곡 쌓고 최신 동향에 맞게 디벨롭하여
동작 원리를 중심으로 자바스크립트에 대해 설명해주신다면,
정말 많은 분께 도움이 되리라 생각합니다.
출간 의사가 있으시면 과정에 대해 메일로 설명해 드리거나
대면 또는 비대면 미팅을 진행할 수 있습니다.
충분히 생각해보시고 원하시는 집필 주제가 따로 있다면 편하게 제안해주셔도 됩니다.
참고로, 제 메일은 Laurence@bjpublic.co.kr입니다.
그럼, 설레는 마음으로 답변 기다리고 있겠습니다.
감사합니다.
최규리 올림