this binding

Seung·2022년 2월 25일
0

JavaScript를 이용하며 미니 프로젝트를 하는 도중 아리송한 오류를 발견하여 그에 대한 설명과 해결방법을 써볼려고 한다.

😄 오류

아래 코드는 실제 프로젝트에서 사용한 코드이다.

/* field.js */
export default class Field {
	constructor() {
    	this.field.addEventListener('click', this.onClick);
  	}
  
onClick(event) {
	this.itemClick('this.binding?');
  /* ...생략 */
};

setClickListener(itemClick) {
	this.itemClick = itemClick;
}
  
/* main.js */
const field = new Field();
field.setClickListener(fieldClick);

function fieldClick(item) {
  /* ...생략 */
}  
  
  • 먼저 field.js에서 Field 클래스를 만들고 이벤트 핸들러를 등록한 뒤 onClick 함수를 콜백함수로 사용하였다

  • 이후 main.js에서 Field 객체를 생성하고 fieldClick 함수를 호출하였다. 여기서 의아했던건 field.js에서 fieldClick함수를 콜백함수로 넘겨받고 실행할 떄 undefined로 나왔다는 것이다. (콘솔 창에는 오류도 안뜸😂🤣😂)

  • 위 오류 떄문에 fieldClick의 코드들이 실행조차 안되는 불상사가 일어났고 콘솔 창에는 무슨 오류인지 나오지도 않아서 한참 해매다가.... 구글선생님을 통해 this binding에 대해 알게되었고 결국 오류를 해결했다.


😄 해결

this binding?
JavaScript는 클래스 안의 어떤 함수를 콜백함수로 전달할 때는 그 함수가 포함하고 있는 클래스의 정보가 사라진다. 이걸 해결하기 위해 this와 클래스를 묶는 것을 this binding이라고 한다.

즉 위의 코드에서 onClick 함수는 Field 클래스의 멤버함수이고 내부 코드는 setClickListener 함수를 통해 가져온 main.js에 있는 fieldClick 함수를 field 이벤트 핸들러에 등록하는 역할을 한다.
그래서 this를 사용하여 this.onClick을 콜백함수로 전달하면 클래스 정보도 함께 전달 되어야 하는 것이 일반 상식이지만 (적어도 다른언어에서는...) JavaScript에서는 딸랑 함수만 전달된다. (참고로 클래스에서는 자신의 멤버 변수를 참조할 때 항상 this를 붙여줘야한다)

따라서 함수만 전달되는 현상을 막고 클래스 정보도 같이 보내고 싶을 때 this binding을 사용한다.

this binding을 하는 방법은 크게 3가지가 있다.
1. 직접적으로 연결하기
this.onClick에 bind를 직접 설정하는 방법
-> this.onclick = this.onclick.bind(this);

2. this가 유지되는 arrow function 사용하는 방법
-> this.field.addEventListener('click', (event) => this.onClick(event));

3. 콜백 함수로 사용할 클래스 내부의 함수를 멤버 변수로 만드는 방법
-> onClick = (event) => { }

본인은 1번의 방법을 사용했고 코드 한줄로 오류 간단하게 해결했다


😍 코드 지적은 언제나 환영입니다. 읽어주셔서 감사합니다. 😍

profile
지적은 제 발전의 원동력입니다. 사소한 것이라도 지적해주세요 :)

0개의 댓글