항해 16기

[항해 4일차] TIL_4주차 : 콜백 함수 내부의 this 에 다른 값 바인딩하기

해갈 2023. 8. 17. 15:47

오늘은 4주차 강의와 함께

어제까지 제출인줄 알았지만, 실은 오늘(08/17)까지 제출해야 하는 

'숫자야구 게임' 을 조별과제를 기능구현은 어제부로 마감했고,

더 추가하고 싶은 기능에 대해 이야기 나눠보고,

추가 기능들을 각자 시간을 갖고 구현한 다음,

화면공유를 통해 서로의 코드를 리뷰하는 시간을 가졌습니다.

하면서, 멘토같은 팀원분의 조언을 듣고 진행을 해서 그런지

코드리뷰 방식은 척척 진행이 되었습니다.

하지만, 모두 처음 해본 경험이어서 제 자신이 쓴 코드이지만,

이를 다른 사람에게 설명하는 것과 그리고, 같은 기능을 구현하는 내용의 코드이지만,

다른 사람이 작성한 코드를 보고, 해석하는 것이 꽤나 어려운 작업이라는 것을 새삼 알게 되었습니다.

https://mimi-kkokko.notion.site/16-1-a47b70fbe8d54d5d8fafc221a53bfc7a

 

[항해 16기] 1주차 팀과제 제출

📸 팀과제 실행 사진

mimi-kkokko.notion.site

https://github.com/yngjnhyk/baseball_game/tree/main

 

GitHub - yngjnhyk/baseball_game

Contribute to yngjnhyk/baseball_game development by creating an account on GitHub.

github.com

콜백 함수 내부의 this 에 다른 값 바인딩하기

콜백 함수도 함수다

콜백 함수로 어떤 객체의 메서드를 전달하더라도, 해당 메서드는 메서드가 아닌 함수로 호출합니다.

const obj = {
	vals: [1, 2, 3],
	logValues: function(v, i) {
		console.log(this, v, i);
	}
};

//method로써 호출
obj.logValues(1, 2); 
// {vals: Array(3), logValues: ƒ}logValues: ƒ (v, i)vals: (3) [1, 2, 3][[Prototype]]: Object 1 2

//callback => obj를 this로 하는 메서드를 그대로 전달한게 아니에요
//단지, obj.logValues가 가리키는 함수만 전달한거에요(obj 객체와는 연관이 없습니다)
[4, 5, 6].forEach(obj.logValues);
// Window {0: Window, window: Window, self: Window, document: document, name: '', location: Location, …} 4 0
// Window {0: Window, window: Window, self: Window, document: document, name: '', location: Location, …} 5 1
// Window {0: Window, window: Window, self: Window, document: document, name: '', location: Location, …} 6 2
콜백 함수에서 this 는 객체의 메서드를 전달하더라도 함수호출을 호출하는 것이 아니라, 함수자체를 콜백함수로 호출하는 것이기 때문에 this 는 전역객체인 Window 를 가리킬 수 밖에 없습니다.

그럼 콜백 함수 내부에서 this 가 문맥에 맞는 객체를 바라보게 할 수는 없을까요?

있습니다! 콜백 함수 내부의 this 에 다른 값으로 바인딩하는 방법은 다음과 같은데요.

 

전통적 방식

이전에 강제로 this 를 제어하는 방법에 대해 살짝 다뤘던 방식입니다.

var obj1 = {
	name: 'obj1',
	func: function() {
		var self = this; //이 부분!
		return function () {
			console.log(self.name);
		};
	}
};

// 단순히 함수만 전달한 것이기 때문에, obj1 객체와는 상관이 없어요.
// 메서드가 아닌 함수로서 호출한 것과 동일하죠.
var callback = obj1.func();
setTimeout(callback, 1000);
// 7133
// (1초 뒤)obj1

실제로 this 를 사용하는 것이 아니기도 하고, 무엇보다 코드양도 많아 외우기도 번거롭습니다.

 

bind 메서드 활용

이외에도 다른 방법들이 있지만, 가장 좋은 방법으로는 bind 메서드를 활용하는 방법이 있습니다.

var obj1 = {
	name: 'obj1',
	func: function () {
		console.log(this.name);
	}
};
//함수 자체를 obj1에 바인딩
//obj1.func를 실행할 때 무조건 this는 obj1로 고정해줘!
setTimeout(obj1.func.bind(obj1), 1000);

var obj2 = { name: 'obj2' };
//함수 자체를 obj2에 바인딩
//obj1.func를 실행할 때 무조건 this는 obj2로 고정해줘!
setTimeout(obj1.func.bind(obj2), 1500);


// 9386
// 1초 뒤 obj1
// 2초 뒤 obj2

 

콜백지옥과