-
addEventListener에서의 this개발/Javascript 2022. 7. 19. 01:48
1. 함수 리터럴(function 키워드 사용)을 이용해 리스너를 만드는 경우
여기에서 this는 이벤트 객체의 currentTarget과 동일합니다.
즉, 예제에서 my_element가 window면 this는 window 객체를 가리키고
my_element가 document이면 this는 document 객체를 가리킵니다.
my_element.addEventListener('click', function (e) { console.log(this.className) // my_element의 className 기록 console.log(e.currentTarget === this) // `true` 기록 })
다음 예제와는 구분을 지어야 합니다.
function Person() { // Person() 생성자는 `this`를 자신의 인스턴스로 정의. this.age = 0; setInterval(function growUp() { // 비엄격 모드에서, growUp() 함수는 `this`를 // 전역 객체로 정의하고, 이는 Person() 생성자에 // 정의된 `this`와 다름. this.age++; }, 1000); } var p = new Person();
2. 화살표 함수로 리스너를 만드는 경우
화살표 함수는 this나 super에 대한 바인딩이 없습니다.
대신에 스코프 체인을 통해 외부 범위에서 this를 찾습니다.
다음 예제에서 만약 화살표 함수가 아니라
함수 리터럴로 리스너를 만들면 this는 window 객체를 가리킵니다.
class SomeClass { constructor() { this.name = 'Something Good'; } register() { window.addEventListener('keydown', (e) => { console.log(this); }); } } const myObject = new SomeClass(); myObject.register();
3. 클래스 메소드를 리스너로 만드는 경우
클래스 메소드인 리스너 안에 this가 사용될 때 1번 규칙(함수 리터럴 사용)이 적용됩니다.
그러므로 이 경우에는 this가 객체를 가리키게 하기 위해 리스너 함수에 this를 바인드 해야 합니다.
const Something = function(element) { // this는 Something 인스턴스 this.name = 'Something Good'; this.onclick1 = function(event) { console.log(this.name); // undefined, this는 element임 }; this.onclick2 = function(event) { console.log(this.name); // 'Something Good', this는 Something 인스턴스 }; // bind가 onclick2의 this 맥락을 고정함 this.onclick2 = this.onclick2.bind(this); element.addEventListener('click', this.onclick1, false); element.addEventListener('click', this.onclick2, false); } const s = new Something(document.body);
4. 리스너를 클래스 메소드가 아니라 프로퍼티로 만들 때(화살표 함수 이용)
리스너를 화살표 함수로 만들었던 2번 규칙과 동일합니다.
화살표 함수는 this 컨텍스트가 없으므로 스코프 체인을 거슬러 올라가 외부에서 찾습니다.
class Keyboard { #addEvent() { document.addEventListener('keydown', this.#onKeydown); } ... // 리스너를 전달할 때 this를 바인드하지 않아도 정상 동작 #onKeydown = (event) => { const key = this.#getKeyboardKey(event); key?.classList.add('active'); }; }
> 참고
https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Functions/Arrow_functions
https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Functions/Method_definitions
https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Classes
https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Operators/this
https://developer.mozilla.org/ko/docs/Web/API/EventTarget/addEventListener
'개발 > Javascript' 카테고리의 다른 글
package.json 모듈 업데이트 (0) 2022.08.03 [Jest] 간단한 유닛 테스트(feat.setTimeout()) (0) 2022.08.02 [TypeScript] ReturnType, const (0) 2022.07.13 [Clouser] 아주 아주 간단한 클로저 기본 (0) 2022.07.08 [Koa] 프레임워크에서 static 파일 경로 설정하기 (0) 2022.07.06