만약 this에 내가 직접 원하는 대상을 바인딩하고 싶다면?

3-2-1 call 메서드

<aside> 💡

call 메서드는 메서드의 호출 주체인 함수를 즉시 실행하도록 하는 명령이다. 내가 Function이라는 함수를 실행할 때, 이 Function 함수를 호출하는 주체, 즉 this를 내가 원하는 대상으로 변경하기 위해 사용한다.

</aside>

Function.prototype.call(thisArg[, arg1[, arg2[, ...]]])

호출할 함수의 내부 this가 첫번째 인자로 넘겨준 대상에 바인딩된다. 나머지 인자는 호출할 함수의 매개변수로 한다.

함수의 경우

그냥 함수를 호출하면 this는 전역 객체를 참조한다. 그러나 call 메서드를 사용하여 임의의 객체를 참조하도록 할 수 있다.

var func  = function (a, b, c) {
  console.log(this, a, b, c)
}

func(1, 2, 3)                 // Window 1 2 3
func.call({ x: 1 }, 4, 5, 6)  // { x: 1 } 4 5 6

메서드의 경우

객체의 메서드를 그냥 호출하면 this에 호출한 메서드가 바인딩된다. 그러나 call 메서드를 사용하면 임의의 객체를 참조할 수 있다.

var obj = {
  a: 1,
  method: function (x, y) {
    console.log(this.a, x, y)
  }
}

obj.method(2, 3)  // 1, 2, 3
obj.method.call({ a: 4 }, 5, 6)  // 4, 5, 6

3-2-2 apply 메서드

<aside> 💡 apply 메서드는 call 메서드와 동일하다. 단 배열을 인자로 받아 호출할 함수의 매개변수로 사용한다는 차이점이 있다.

</aside>

var func = function (a, b, c) {
  console.log(this, a, b, c)
}
func.apply({ x: 1 }, [4, 5, 6]) // { x: 1 }, 4, 5, 6

var obj = {
  a: 1,
  method: function (x, y) {
    console.log(this.a, x, y)
  }
}

obj.method.apply({ a: 4 }, [5, 6])  // 4, 5, 6