[TIL] Call, Apply, Bind

ytwicey·2020년 11월 7일
0

TIL

목록 보기
9/23

Cominciamo

이전 this의 블로깅에 이어서, call, apply, bind를 이야기 해보겠다.
This가 함수가 호출됨에 따라 객체를 가르켰다면, 이번에는 call, apply, bind는 this의 범위를 특정할 수 있다. 오늘의 블로깅은 여기를 참고했음.


기본적으로 알고가야 하는 내용

  • 함수는 기본적으로 객체다.

Every JavaScript function is actually a Function object. This can be seen with the code (function(){}).constructor === Function, which returns true.

MDN에서 가져온 함수의 정의(?)다. 해석해보자면,

자바스크립트의 모든 함수는 사실 함수 객체다. 코드로 볼 수 있는데 function(){}).constructor === Function라고 하면 true를 리턴한다.

그러니까 함수 객체이기 때문에, 변수 프로퍼티와 함수 프로퍼티를 갖는다. 그리고 이 함수 프로퍼티를 우리는 메소드라고 부른다.

함수객체는 아래와 같은 메소드를 갖는다. 대표적으로 apply, call, bind, toString이 있다. (그래서 우리가 OOP를 볼때 그렇게도 toString을 찾았던가....?)

그러니까 우리는 함수이름.call(), 함수이름.apply(), 함수이름.bind(), 이렇게 사용할 수 있다.

그렇다면 이 메소드들은 어떤 경우에 쓰는 것인가?

call, apply, bind는 기본적으로 함수의 실행영역을 지정하는 메소드다. 위 세 개의 함수는 .call/apply/bind()안에 할당되는 첫번째 인자를 this로 간주한다. 함수 자신의 실행"환경"을 외부 this로 설정할 수 있는 것이 주요한 특징이라고 생각하며 된다.

1. .Call() & .Apply()

MDN에서 말하길, 두 메소드의 차이점은 아래와 같다.

공통점은 함수를 호출해 실행시킨다는 것이다. 따라서 Call만 기술하겠다.

call()은 이미 할당되어있는 다른 객체의 함수/메소드를 호출하는 해당 객체에 재할당할때 사용됩니다. this는 현재 객체(호출하는 객체)를 참조합니다. 메소드를 한번 작성하면 새 객체를 위한 메소드를 재작성할 필요 없이 call()을 이용해 다른 객체에 상속할 수 있습니다.

MDN에서 말하는 Call()의 역할은 위와 같다.
이에 따른 예시를 살펴 보자.

2. 예시

2-1. 객체의 생성자 연결에 call 사용(OOP)

객체의 생성자 연결(chain)에 call을 사용할 수 있다. 위 예에서, Product 객체의 생성자는 name 및 price 를 매개변수로 정의된다. 다른 두 함수 Food는 this 및 name과 price를 전달하는 Product를 호출합니다. Product는 name 및 price 속성을 초기화한다.

여기서는 this가 Product의 속성을 상속받아오는 역할을 함.

2-2. 익명 함수 호출에 call 사용

이 부분은 이해를 제대로 하지 못했지만, 요점은 익명함수를 적용할 배열을 지정했다는 것. 따라서 this의 범위를 특정했다는 것만 이해하고 넘어가쟈...

2-3. 함수 호출 및 'this'를 위한 문맥 지정에 call 사용

이것도 마찬가지로, greet()라는 함수를 호출하면, this의 범위는 obj로 특정된다.


그러나 .call() 사용하면 This는 전역객체 window에 바인딩되고, strict-mode에서는 undefined가 나온다.

3. .Bind()

call(apply)과 유사하게 this 및 인자를 바인딩하나 두 메소드의 차이점은 실행시점이다. call(apply)는 엔터를 내려치는 것(??????)과 동시에 함수실행이 되지만, bind는 당장 실행하는 것이 아닌 바인딩된 함수를 리턴하는 메소드다.

4. 예시

4-1. setTimeout()

보통 setTimeout()에서 많이 쓰는데, 아래와 예제를 보자.

위 예제에서는 box.printAsync()에서 에러가 난다. 왜냐하면 setTimeout에서 this의 디폴트값은 window이기 때문이다. 그렇기 때문에 이 this의 범위를 바꿔줘야한다. 그러나 call/apply는 즉시 실행되기 때문에 setTimeout가 의미가 없다. 따라서 bind를 써서 활용한다.

제대로 작성하면 아래와 같다.


Finiamo

사실 바인드의 예시에는 이벤트 핸들러도 있는데, 아직 확실하게 이해를 못해서 설명을 할 수 없었ㄷ.......
그렇지만 이 포스팅의 이점은 함수는 객체라는 것을 좀 확실하게 정리했다는 것. 이전에 티스토리 포스팅에서 마무리짓지 못하고 임시글로 남겨둔게 마음에 걸렸는데, 이제 하나는 이해하게 돼서 기쁘다.

profile
always 2B#

0개의 댓글