개발일지

Function.call , Function.apply , Function.bind

• javascript

this바꾸기

Function.call , Function.apply , Function.bind
세 함수 모두 사용법에 차이가 있고, 특징이 다릅니다만,
공통적으로 함수를 간접 호출하면서 this를 바꾸는 역활 을 수행할 수 있습니다.

예를 들어 Math.max(arg1,arg2…)함수는 인자로 들어온 숫자 중에서 가장 큰 숫자를 반환합니다.

  > Math.max(1,2)
  < 2

Function.call

Math 함수를 Function.call 함수로 간접 호출하는 방법은 다음과 같습니다.
첫번째 인자로 this가 될 객체를 넘겨주고, Math함수에 넘길 인자들을 두번째 인자부터 차례대로 입력합니다.

  > Math.max.call(Math,1,2)
  < 2

따라서 다음과 같은 응용이 가능합니다.

See the Pen Function.call 예제 by cinos (@shoveller) on CodePen.

html엘리먼트를 전달하면 Array.prototype.sort를 사용해서 정렬도 할 수 있습니다.

See the Pen Array.prototype.sort로 테이블 정렬하기 by cinos (@shoveller) on CodePen.

Function.apply

Math 함수를 Function.apply 함수로 간접 호출하는 방법은 다음과 같습니다.
첫번째 인자로 this가 될 객체를 넘겨주고, Math함수에 넘길 인자들을 배열로 넘기는 것이 특징이네요.

  > Math.max.apply(Math,[1,2])
  < 2

따라서 다음과 같은 응용도 가능합니다.
다음 예제는 외부의 객체를 setTimeOut함수의 this로 지정하고 있습니다.

See the Pen setTimeOut에 Function.apply로 this지정하기(1) by cinos (@shoveller) on CodePen.

Function.bind

Math 함수를 Function.bind 함수로 간접 호출하는 방법은 다음과 같습니다.
얼핏 보아서는 call 함수와 비슷하지만 this가 바뀐 함수를 새로 만들어서 리턴 한다는 점이 가장 큰 특징입니다.
따라서 실행을 위해선 ()를 한번 더 적어줘야 합니다.

  > Math.max.bind(Math,1,2)
  < max() { [native code] }
  > Math.max.bind(Math,1,2)()
  < 2

이러한 Function.bind의 특성은 사용자가 만든 객체의 값을 받아서 실행시키는 함수를 작성할 때 매우 유용합니다.

  > var sum = function(y,z){return this.x + y + z;};
  < sum.bind({x:1},2)(3);
  < 6

위 코드에서 익명 객체 {x:1}과 2를 사용하면,익명객체를 this로 참조하는 sum함수가 새로 만들어집니다.
따라서 새로 만들어진 sum함수 안의 x는 익명객체의 x가 됩니다. 그리고 y는 2가 됩니다.
마지막으로 실행시에 3을 넘기면 파라미터 z위치에 3이 입력됩니다.
즉, 사용자 정의 객체 {x:1}을 마련하고 -> 함수객체를 생성하고 -> 인수를 추가해서 실행
이 경우에는 함수호출을 무려 세 단계로 나눌 수가 있었네요!

따라서 Function.call을 대체할 수 있습니다.

다음의 예제는 Function.bind를 사용하여 setInterval함수에 this를 지정해 주고 있습니다.

See the Pen setInterval함수의 this를 Function.bind로 제어하기 by cinos (@shoveller) on CodePen.

다음의 예제는 Function.bind를 사용하여 setTimeOut함수에 this를 지정해 주고 있습니다.

See the Pen setTimeOut에 Function.bind로 this지정하기(2) by cinos (@shoveller) on CodePen.

김영보 선생님의 자바스크립트 강좌에 따르면 실무에서는 다음과 같이 사용할 수 있다고 하네요.
이벤트 핸들링을 위임하는 객체를 별도로 생성해서 이벤트를 다루어야 할 경우에 매우 유용하게 사용될 것 같습니다.
이벤트 객체의 this를 바꿀 수 있다니.. 멋진 아이디어입니다.

See the Pen addEventListener대신 Function.bind 사용하기 by cinos (@shoveller) on CodePen.

comments powered by Disqus