TIL 2023.05.25

jomok·2023년 5월 25일
0
post-thumbnail

오늘 공부 계획 및 공부한 내용📝

  • 3주차 후반부 복습&질문, 4주차 들어가기 ㅇ
  • call, apply, bind 이해하고 넘어가기

call, apply, bind

자동으로 부여되는 상황별 this규칙을 깨고 명시적으로 this를 지정하려면
call / apply / bind 를 함께 사용하면 된다.

- call 메서드

기존에 있었던 메서드 뒤에 붙어서 즉시 실행해주되
명시적으로 binding할 객체(this로 지정할 객체)를 뒤에 써줘야 함.

- apply 메서드

call 메서드와 완전히 동일.
but! this에 binding할 객체는 똑같이 넣어주고 나머지 부분만 배열 형태로 넘겨줌.

  • call / apply 메서드 활용

1) 유사배열객체(array-like-object)에 배열 메서드를 적용
2) Array.from 메서드(ES6)
3) 생성자 내부에서 다른 생성자를 호출(공통된 내용의 반복 제거)
4) 여러 인수를 묶어 하나의 배열로 전달할 때 apply 사용 가능

//apply는 (this로 엮을 인자, 배열)을 받아야 함, 일부러 this를 안 넣겠다 해서 null 
var numbers = [10, 20, 3, 16, 45];
var max = Math.max.apply(null, numbers);
var min = Math.min.apply(null, numbers);
console.log(max, min);

- bind 메서드

call과는 다르게 즉시 호출하지는 않고 넘겨받은 this 및 인수들을 바탕으로
새로운 함수를 반환하는 메서드
함수에 this를 미리 적용하고 부분 적용 함수 구현할 때 용이함.

var func = function (a, b, c, d) {
	console.log(this, a, b, c, d);
};
func(1, 2, 3, 4); // this는 window객체

// 함수에 this 미리 적용
var bindFunc1 = func.bind({ x: 1 }); // 바로 호출되지는 않아요! 그 외에는 같아요.
bindFunc1(5, 6, 7, 8); // { x: 1 } 5 6 7 8

// 부분 적용 함수 구현
var bindFunc2 = func.bind({ x: 1 }, 4, 5); // 4와 5를 미리 적용
bindFunc2(6, 7); // { x: 1 } 4 5 6 7
bindFunc2(8, 9); // { x: 1 } 4 5 8 9

++ bind 메서드 활용) 상위 컨텍스트의 this를 내부함수나 콜백 함수에 전달

var obj = {
	outer: function() {
		console.log(this);
		var innerFunc = function () {
			console.log(this); //{ outer: [Function: outer] }출력
		}.bind(this); // innerFunc에 this를 결합한 새로운 함수를 할당
		innerFunc();
	}
};
obj.outer(); //{ outer: [Function: outer] }출력

- 화살표 함수의 예외사항

화살표 함수는 실행 컨텍스트 생성 시, this를 바인딩하는 과정이 제외
스코프체인상 가장 가까운 this에 접근하고 this우회, call, apply, bind보다 편리한 방법


문제🧐 / 해결과정⚒️

1) obj늪..

🤔--> obj1.outer(); 에 의해서 2번째줄 실행 -> console.log(this);에서 this가 처음으로 호출되고 그 호출의 주체 객체 obj1가 찍힌 거까지는 알겠는데...

왜 { outer: [function: outer]} 이 찍혔지 {outer: fun} 이 아니라?
아님 {outer: fun()}로 찍히던가
왜 굳이 저 fun () 안에 outer가 들어갔을까
여기저기 떠들어 봤지만 해결을 못했다..


🤔-->여기도 마찬가지. 굳이 function가 써진 이유는..?


2) bind를 써서 상위 컨텍스트의 this를 콜백 함수에 전달할 수 있는데
setTimeout이라는 함수의 첫 등장과 함께 콜백함수의 개념이 혼란의 카오스를 만들었다..

🤔 가운데 setTimeout(this.logThis, 500); 가 실행되었을 때 obj라는 주체 설정까지 해줬는데
왜 자꾸 this가 전역 객체를 참조해 정상동작하지 않는지 이해가 되지 않았다.

📌 애초에 obj.logThisLater1();에서 지정해준 Obj라는 주체는
this.logThis 함수가 실행되었을 때 그냥 인용된 것이지
그 안에 결과값인 console.log(this)의 this는 될 수 없는 거였다.
즉 this가 지정되지 않은 상태! 그래서 this가 전역 객체를 참조에 결과가 그렇게 나온 것

반면 obj.logThisLater2(); 결과값은 binding을 해줬기 때문에
setTimeout(this.logThis.bind(this), 1000);가 실행되면
1초를 뒤 아래와 같이 정상동작하여 출력된다.

{
  logThis: [Function: logThis],
  logThisLater1: [Function: logThisLater1],
  logThisLater2: [Function: logThisLater2]
}

bind를 쓰면 상위 컨텍스트의 this를 내부함수나 콜백 함수에 전달할 수 있어 좋은데
그 상위 컨텍스트가 무엇인지, 그 컨텍스트의 this는 무엇인지 제대로 파악하는 게
아주 중요한 것 같다..

📌 콜백함수
다른 코드의 인자로 넘겨주는 함수

다른 코드(함수 또는 메서드)에게 인자로 넘겨줌으로써 그 제어권도 함께 위임

setTimeout 함수는
콜백 함수를 호출할 때(위에서는 this.logThis) 대상이 될 this를 지정하지 않으면
this는 곧 window객체!

왜? 콜백 함수도 함수이기 때문에 기본적으로 this가 ‘전역 객체’를 참조
🔥 예외! 제어권을 넘겨받을 코드에서
콜백 함수에 별도로 this가 될 대상을 지정한 경우에는 그 대상을 참조한다.


느낀점✨

  • 코드 읽는 법을 배워가서 좋긴 한데.. 개념이 하나 둘 늘어갈 때마다
    저장-리셋 과정을 번갈아 가면 머리 안이 아주 난리다 ㅎㅎㅎㅎㅎ 진도는 나가야겠는데
    분명 들었던 내용, 이해했던 내용인데 다시금 ㅇ,ㅇ? 이게 뭐더라? 하고 다시 리턴하게 된다ㅎㅎㅎ
    정말 계속해서 들어도, 고민해도 도저히 이해가 되지 않는 부분들이 있는데
    그럴 때마다 동기들이 있어 얼마나 다행인지 모른다..
    정말 어제도 9시반에 공부를 끝내고 거의 12시까지 열띤 q&a시간을 가졌다 ㅎㅎㅎ
    신기한 게 셋 다 모르겠는데 이리저리 배운 개념과 내용들을 가지고 서로 얘기하다 보면
    몰랐던 내용도 "아! 나 알겠다!!"를 외치게 된다ㅎ
    셋 중 한명만 걸려라는 심정으로 각자의 생각들을 나누는 시간...ㅋㅋㅋ
    아 이 과정과 고비를 하나 둘 지나고 보면 우리 모두 코드를 혼자 읽을 때가 오겠지..🥹 화이팅...!

0개의 댓글