JavaScript에서는 일반적인 방법 외에도 함수를 어디에서 어떻게 호출했는지에 상관없이 this가 무엇인지 지정할 수 있다.
먼저 call부터 살펴보자. call 메서드는 모든 함수에서 사용할 수 있으며 this를 특정 값으로 지정할 수 있다. 다음 예제를 살펴보자. 여기에서 this는 window를 가리킨다. window.name이 빈 문자열이기 때문에 이렇게 나오는 것이다.
이때 showThisName()에 call을 해주고 이곳에 mike를 전달해보자. 그러면 Mike가 나온다. 함수를 호출하면서 call을 사용하고 this로 사용할 객체를 넘기면 해당 함수가 주어진 객체의 메서드인 것처럼 사용할 수 있다. call의 첫 번째 매개변수는 this로 사용할 값이고, 매개변수가 더 있으면 그 매개변수를 호출하는 함수로 전달된다.
tom도 해보자. 콘솔에 Mike와 Tom 둘 다 잘 나온다. call을 통해 this가 mike가 되었다가 tom이 된 것이다.
이번에는 업데이트 함수를 살펴보자. 업데이트 함수는 생년과 직업을 받아서 객체의 정보를 새로운 데이터로 업데이트해준다. 업데이트에 call을 하고 this로 사용할 mike를 전달한 뒤, 두 번째 매개변수로 생년, 세 번째는 직업을 전달했다. 이렇게 하고 mike를 확인해 보면 생년과 직업이 들어간 걸 볼 수 있다.
tom도 한번 해보자. 객체의 정보가 의도한 대로 업데이트되었다. 다시 요약하자면 첫 번째 매개변수는 this로 사용될 값이다. 두 번째 매개변수부터는 해당 함수가 사용할 매개변수들을 순서대로 적은 것이다.
이번에는 call과 비슷한 apply를 알아보자. 함수 매개변수를 처리하는 방법을 제외하면 apply는 call과 완전히 같다. call은 일반적인 함수와 마찬가지로 매개변수를 직접 받지만, apply는 매개변수를 배열로 받는다. 위 코드를 call에서 apply로 바꾸면 다음과 같다. 결과는 동일하다.
apply는 배열 요소를 함수 매개변수로 사용할 때 유용하다. 최소값과 최대값을 구하는 코드를 살펴보자.
Math.min에 배열 자체를 넣으면 NaN이 나온다.
이제 이렇게 있다고 가정하고 이 배열을 풀어서 넣어줘야 하는데 스프레드 연산자를 활용해보자.
스프레드 연산자를 쓰면 결괏값이 잘 나온다.
이제 apply를 써보자. apply는 두 번째 매개변수로 배열을 전달하면 그 요소들을 차례대로 인수로 사용한다. 그러니까 이렇게 해주면 된다. 결과는 동일하다. 여기에서 null은 this로 사용될 값인데 Math.min이나 Math 메서드는 딱히 this가 필요하지 않아서 아무거나 입력해도 상관없다.
call을 사용할 수도 있다. call은 차례대로 매개변수가 들어가야 하니까 스프레드 연산자를 쓰면 된다. 동일한 결과가 나온다. call과 apply의 차이를 잘 확인해두자. call과 apply는 동작 방식은 같다. 매개변수를 받는 방법만 다를 뿐이다. call은 순서대로 직접 받고, apply는 배열 형태로 받는다. 둘이 헷갈릴 때는 apply는 array를 받는다. 이렇게 a로 묶어서 기억하면 편하다.
this 값을 바꿀 수 있는 마지막 함수는 bind이다. bind를 사용하면 함수의 this 값을 영구히 바꿀 수 있다. 아까 봤던 update 함수를 이리저리 옮기면서 호출할 때, this 값이 항상 mike가 되게 하려면 bind를 쓰면 된다. updateMike를 한번 만들어보자. 여기에서 bind는 새로 바인딩한 함수를 하나 만든다. 이 함수는 항상 mike를 this로 받는다.
이렇게 사용하면 된다.
실사용 예제를 살펴보자. 이 코드에서 fn이란 걸 만들고 user.showName을 줬다. 이때 fn()을 호출하면 아무것도 뜨지 않는다. fn을 할당할 때 this를 잃어버린 것이다.
메서드는 점 앞에 있는 게 this이다. 호출할 때 fn()만 호출하니까 this가 없는 것이다. 이럴 때는 call을 써보자. fn에 call을 하고 this로 사용할 값 user를 넣어주면 된다. 그러면 결과가 잘 나온다.
apply로 해도 결과는 동일하다.
이번에는 bind를 이용해서 새 함수를 만들어보자. boundFn이란 걸 만들고 fn에 bind를 가져오고 this 값으로 user를 갖도록 했다.
출처: 코딩앙마, 자바스크립트 중급 강좌 #13 call, apply, bind