일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | |||
5 | 6 | 7 | 8 | 9 | 10 | 11 |
12 | 13 | 14 | 15 | 16 | 17 | 18 |
19 | 20 | 21 | 22 | 23 | 24 | 25 |
26 | 27 | 28 | 29 | 30 | 31 |
- eager
- 이진탐색
- 즉시로딩
- PS
- SQL프로그래밍
- 지연로딩
- FetchType
- 백트래킹
- 스토어드 프로시저
- fetch
- 다대다
- 연관관계
- 비관적락
- 낙관적락
- 다대일
- 힙
- BOJ
- JPQL
- dfs
- 데코레이터
- CHECK OPTION
- execute
- 동적sql
- exclusive lock
- 스프링 폼
- 유니크제약조건
- shared lock
- 연결리스트
- 일대다
- querydsl
- Today
- Total
흰 스타렉스에서 내가 내리지
[JS] class에서 this 바인딩에 대해 본문
<body>
<button>print 'nothing' in conole</button>
</body>
이 버튼을 누르면, 콘솔에 nothing이 찍히게 하고 싶다.
만약 js파일에 코드가 이렇게 짜여져 있다면,
class Nothing {
constructor() {
this.nothing = document.querySelector("button");
this.nothing.addEventListener("click", this.callPrintNothing); // << 4번째 라인
}
printNothing() {
console.log("nothing");
}
callPrintNothing() {
this.printNothing();
}
}
const nothing = new Nothing();
버튼을 아무리 눌러도 콘솔에는 메시지가 찍히지 않는다. 어째서일까?
4번째 라인에 this.callPrintNothing()에 주목하자.
addEventListener에 this.callPrintNothing 을 넘겨 주었으므로 this에 해당하는 Nothing 클래스 정보도 넘어갔을 것 같지만, 그렇지 않다. 자바스크립트에서는 클래스가 무시된 채로 '함수만' 전달이 된다.
즉, 클래스 정보는 콜백으로 전달되지 않는다.
클래스 정보가 넘어가지 않았으므로, callPrintNothing() 함수 내부에서는 "아 this.printNothing()함수를 호출하면 되겠구나. 근데 this가 뭐지?" 가 되어버린다.
callPrintNothing이 다른 곳으로 콜백이 전달되었을 때는, this가 존재하지 않아 printNothing()은 계속 undefined 상태이다.
따라서 클래스 정보까지 콜백으로 보내주고 싶다면, 함수를 클래스와 바인딩을 해줘야 한다. 이것을 this 바인딩이라고 한다.
# 해법1
// bind 함수 이용
class Nothing {
constructor() {
this.nothing = document.querySelector("button");
this.callPrintNothing = this.callPrintNothing.bind(this); // ***추가***
this.nothing.addEventListener("click", this.callPrintNothing);
}
printNothing() {
console.log("nothing");
}
callPrintNothing() {
this.printNothing();
}
}
const nothing = new Nothing();
직접적으로 bind() 함수를 이용하여 클래스와 bind 해준다.
# 해법2
class Nothing {
constructor() {
this.nothing = document.querySelector("button");
this.nothing.addEventListener("click", () => this.callPrintNothing()); // ***수정***
}
printNothing() {
console.log("nothing");
}
callPrintNothing() {
this.printNothing();
}
}
const nothing = new Nothing();
콜백으로 전달되는 함수를, this.callPringNothing() 함수 자체를 줄게 아니라, arrow function으로 한 번 더 감싸준다.
arrow function은 this가 유지되기 때문이다.
# 해법3
class Nothing {
constructor() {
this.nothing = document.querySelector("button");
this.nothing.addEventListener("click", this.callPrintNothing);
}
printNothing() {
console.log("nothing");
}
callPrintNothing = () => { // ***수정***
this.printNothing();
};
}
const nothing = new Nothing();
클래스 안에 있는 어떤 함수를 다른 콜백으로 전달할 때는, 그 함수를 변수화 한다.
즉, callPrintNothing 이라는 변수를 만들고, 그 변수가 우리가 원하는 arrow function 로직을 가리키도록 한다.
결론:
어떤 클래스 안에 있는 함수를 다른 콜백으로 전달할 때는 그 함수가 위치한 클래스의 정보가 사라진다.
따라서 클래스와 함수를 묶는 binding과정이 필요하다.
'Javascript' 카테고리의 다른 글
Date.now().toString()과 new Date().toString() 의 차이 (0) | 2022.04.10 |
---|---|
'!!' 는 js에서 무엇을 의미하는가? (0) | 2022.03.23 |
자바스크립트 최신 문법 (ES6, ES11) (0) | 2022.02.01 |
[JS] 자바스크립트를 깔끔하게 코딩하는 팁 (0) | 2022.01.31 |
[JS] 이벤트 위임 (0) | 2022.01.23 |