development

자바스크립트 call, apply, bind 정리

나는산타 2022. 9. 20. 17:36
반응형

call, apply, bind 함수를 간단히 말하면

이 함수들은 모두 함수 내의 값을 변경하기 위해 사용된다. 각 함수들을 자세히 알아보자.

 

call

call 함수를 사용하면 함수 내부에서 이렇게 처리되는 값을 전달하여 함수를 호출할 수 있다.

const obj = {
  myName: "john",
  printName: function () {
    console.log(this.myName);
  },
};
obj.printName(); // john

const newObj = {
  myName: "peter",
};
obj.printName.call(newObj); //peter

 

위의 코드에서는 파라미터로 newObj를 전달함으로써 printName 함수의 call 함수를 호출하고 있다. 이 printName은 newObj를 가리키고 따라서 this.myName는 peter를 출력한다.

그럼 파라미터를 함수에 넘기려면 어떻게 해야 할까?
call 함수의 첫 번째 파라미터는 함수 내의 this가 가리키는 값이다. 이 함수에 추가 파라미터를 넘기려면 call 함수의 두 번째 파라미터에서부터 파라미터를 전달한다.

 

function foo(param1, param2) {}
foo.call(thisObj, arg1, arg2);

 

foo는 이 값 thisObj를 새 값으로 넘겨줌으로써 호출하는 함수다.

arg1, arg2는 foo 함수가 사용하는 추가 인수다. (param1=arg1, param2=arg2)

 

apply

apply 함수는 call 함수와 매우 비슷하다. call과 apply의 차이점은 인수 전달 방법이다.

- call : 인수를 개별 값으로 넘겨주고 두 번째 인수부터 시작한다.
- apply : 추가 인수는 배열로 넘겨진다.

function sayHello(greet, msg) {
  console.log(`${greet} ${this.name} ! ${msg}`);
}

const obj = {
  name: "peter",
};
sayHello.call(obj, "Hello", "Good Morning"); // Hello peter ! Good Morning
sayHello.apply(obj, ["Hello", "Good Morning"]); // Hello peter ! Good Morning

위의 예제에서 함수에 대한 call과 bind 함수의 sayHello는 동일한 작업을 수행한다. 유일한 차이점은 추가 인수를 전달하는 방법이다.

 

bind

call과 apply 함수와 달리 bind는 함수를 직접 호출하지 않는다. 대신 함수 내부에서 this 값을 변경하고 변경된 함수 인스턴스를 반환한다. 나중에 반환된 함수를 호출할 수 있다.

function sayHello() {
  console.log(this.name);
}

const obj = { name: "peter" };
const newFunc = sayHello.bind(obj); // it won't invoke, it just returns back the new function instance
newFunc(); // peter

 

추가 파라미터 전달

bind 함수에서 추가 파라미터 전달은 call 함수와 유사하다. 두 번째 파라미터부터 시작하는 개별 값으로 추가 파라미터를 전달할 수 있다.

function sayHello(greet) {
  console.log(`${greet} ${this.name}`);
}

const obj = { name: "peter" };
const newFunc = sayHello.bind(obj, "Hello");
newFunc(); // Hello peter

 

bind 함수의 경우, 두 가지 방법으로 추가 인수를 전달할 수 있다.

 

1) bind 함수 자체를 호출하는 동안 this의 값과 함께 추가적인 파라미터를 함수에 전달할 수 있다.

2) 또 다른 방법은 해당 bind 함수의 함수를 호출하는 동안 추가 파라미터를 전달할 수 있다.

 

위의 방법 중 하나를 사용할 수 있고, 기능상의 차이 없이 비슷하게 작동한다.

function sayHello(greet) {
  console.log(`${greet} ${this.name}`);
}

const obj = { name: "peter" };
const newFunc1 = sayHello.bind(obj, "Hello");
newFunc1(); // Hello peter

const newFunc2 = sayHello.bind(obj);
newFunc2("Hello"); // Hello peter

 

call, apply, bind 함수를 호출하는 동안 값을 전달하거나 null을 전달하지 않으면 이 내부 호출 함수는 전역 개체를 가리킨다.

function sayHello() {
  // executing in browser env
  console.log(this === window);
}
sayHello.call(null); // true
sayHello.apply(); // true
sayHello.bind()(); // true

 

하지만 arrow function의 함수의 this는 call, apply, bind 함수를 사용하여 값을 변경할 수 없다. arrow function에는 this 컨텍스트가 없기 때문이다. arrow function의 this는 해당 기능이 있는 상위 기능을 가리킨다. 따라서 arrow function에는 이러한 방법을 적용해도 아무런 효과가 없다.

 

* 원문 : https://medium.com/@makesh-kumar/javascript-call-apply-bind-methods-e2c72e7eca65

반응형