Front-end/JavaScript

JS 동작원리 10편 - call, apply, bind

파리외 개발자 2022. 12. 24. 19:39
//call
function a() {
  console.log("a");
}

a.call(); //a
a.apply(); //a
a(); //a

js의 function에는 call, apply, bind라는 내장 함수가 있다.

이 글에서는 이 세 함수의 특징과 사용법에 집중해서 다루도록 하겠다.

객체의 메서드

const wizard = {
  name: "Merlin",
  health: 70,
  heal(num1, num2) {
    return (this.health += num1 + num2);
  },
  revival() {
    return (this.health = 100);
  },
};

마법사 객체는 이름이 멀린, 체력은 70이다.

또 두 기술을 가지고 있는데 각각 heal과 revival이다.

그럼 마법사 스스로에게 revival을 사용해보도록 한다.

revival사용 후 체력이 70에서 100으로 변했다.

call, apply로 다른 객체의 메서드를 빌릴 수 있다.

const archer = {
  name: "Robin Hood",
  health: 30,
};

//call, apply는 다른 객체의 함수를 빌릴 수 있다.
console.log(archer);
wizard.revival.call(archer);
console.log(archer);

여기 체력이 30인 궁수, 로빈 훗이 있다.

멀린은 이 궁수의 체력을 올려주기 위해 revival을 사용하고자 한다.

그럴 때 call을 사용하면 자신의 체력이 아닌 call의 인자로 지정된 대상의 체력을 올려줄 수 있다.

이전 글에서도 작성했듯이 기본적으로 함수의 this는 전역을,

객체의 메서드의 this는 객체를 가리킨다. (마법사의 revival은 기본적으로 자신의 체력을 회복)

다만 여기서 call, bind, apply 등을 사용하면 this를 해당 객체를 가리키도록 할 수 있다.

그렇기에 멀린의 revival메서드의 this가 archer를 가리키며 궁수의 체력이 회복된다.

apply

console.log(archer);
wizard.heal.apply(archer, [30, 10]); //call(archer,30,10)
console.log(archer);

추가로 마법사는 heal을 사용해 궁수의 체력을 더 올려주기로 한다.

이번엔 call대신 apply를 사용하는데, 차이는 인자를 배열로 전달한다는 것이다.

call을 사용할 때는 배열만 빼주면 동일한 동작을 한다.

bind

console.log(archer);
const healArcher = wizard.heal.bind(archer, 30, 10);
healArcher();
console.log(archer);

bind는 조금 다르다.

바로 실행을 시키는 call, apply와 다르게

해당 동작을 변수에 저장하여 새로운 함수처럼 사용할 수 있다.

Function Currying

커링이란 함수를 커스터마이징 또는 변환한다고 볼 수 있다.

//function currying
function multiply(a, b) {
  return a * b;
}

let multiplyByTwo = multiply.bind(this, 2);
console.log(multiplyByTwo(4));

let multiplyByFive = multiply.bind(this, 5);
console.log(multiplyByFive(4));

두 수를 곱하는 함수가 있을 때 bind를 사용해 2나 5를 저장하고

첫 번째 인자로 this를 받는다면

2가 bind로 저장된 함수는 2를 곱해주고 

5가 저장된 함수는 5를 곱해주게 된다.