웹/Javascript

call, apply, bind

onwah 2019. 8. 3. 00:08

call, apply, bind 이 세 메서드는 유사한 역할을 합니다.

이 셋은 '객체에 속하지 않은' 함수를 '객체에 속하는' 상태로 만들어줄 수 있습니다.

 

1. 일반적인 사용

 

const func = function() {
  this.job = 'developer';
};

객체에 속하지 않은 함수 func가 있습니다.

객체에 속하지 않았기 때문에, 함수의 this는 특정한 객체에 job이라는 프로퍼티를 설정해주지 않습니다.

 

const onwah = {
  name: 'onwah'
}

call, apply, bind의 효과를 체험하기 위해 객체 하나를 만들어줍니다.

 

func.call(onwah);
console.log(onwah.job);

함수를 호출할 때, 그 뒤에 call, bind, apply를 사용합니다. argument로는 함수가 속할 객체를 넘겨줍니다.

func함수는 자신이 속한 객체에 job이라는 프로퍼티를 설정해주고, 'devloper'라는 리터럴을 값으로 넘겨줍니다.

 

결과는 말한대로 

 

 

2. 객체 이외의 전달인자

 call은 특별하게도 첫번째 argument인 객체 이외에도 전달할 argument를 여러개 가질 수 있습니다. 

const func = function( age, height) {
  this.job = 'developer';
  this.age = age;
  this.height = height;
};

함수 func를 확장했습니다. 두 개의 parameter, age와 height를 설정했습니다.

 

func.call(onwah, 45, 197);
console.log(onwah.job);
console.log(onwah.age);
console.log(onwah.height);

 객체인 onwah 뒤로 argument를 추가로 45와 197을 전달했습니다.

그리고 log로 콘솔에 값을 나타내봅니다.

 

결과는 

두 번째 인자부터는 함수의 전달인자로 사용할 수 있는 것을 알 수 있습니다.

 

3. call, apply, bind의 차이점은?

call과 같이 apply와 bind도 같은 목적으로 사용합니다.

그렇다면 차이는 무엇일까요.

 

 

call vs. apply

앞서 call은 첫번째 전달인자인 객체 외에 여러 개의 전달인자를 함수로 넘겨줄 수 있다 하였습니다.

사실 이는 apply도 마찬가지입니다. 

하지만 apply는 여러 개의 전달인자를 하나씩 넘겨주는 것이 아니라 배열 하나로 넘겨줍니다.

 

func.apply(onwah, [45, 197]);

console.log(`${onwah.name} : ${onwah.job}, ${onwah.age}, ${onwah.height}`);

위의 코드에서 객체 이후 전달인자 부분이 배열로 묶였습니다.

결과는

동일한 결과입니다. call과 apply의 차이점은 전달인자가 낱개로 전달되느냐 배열로 전달되느냐 입니다.

 

 

call, apply vs. bind

일회성 사용  vs  재사용 

: call과 apply는 호출할 때마다 첫 번째 argument 값으로 전달되는 객체에 속할 수 있습니다. (여러 객체에 속할 수 있음)

 

const ljs = {
  name: 'ljs'
}

새로운 객체를 하나 만들었습니다.

 

func.call(onwah, 45, 197);
func.call(ljs, 22, 153);

console.log(`${onwah.name} : ${onwah.job}, ${onwah.age}, ${onwah.height}`);
console.log(`${ljs.name} : ${ljs.job}, ${ljs.age}, ${ljs.height}`);

객체 onwah와 ljs를 각각 func.call에 넘겨줍니다.

 

결과는 

함수를 호출할 때마다 첫 번째 인자로 전달된 객체에 프로퍼티와 값이 설정된 것을 볼 수 있습니다.

 

 

bind!

하지만 bind는 인자로 전달된 객체를 계속해서 사용하게 만들 수 있습니다. 

 

const bindedFunc = func.bind(onwah);

새로운 변수에 bind를 호출한 값을 넘겨줍니다.

 

bindedFunc.call(ljs, 22, 153);

console.log(`${onwah.name} : ${onwah.job}, ${onwah.age}, ${onwah.height}`);
console.log(`${ljs.name} : ${ljs.job}, ${ljs.age}, ${ljs.height}`);

이 변수로 call을 호출해 ljs객체와 2개의 argument를 전달합니다.

 

결과는 

ljs에 설정이 되지 않고, onwah에 설정이 되었습니다.

이는 bindedFunc가 영구하게 this값을 onwah로 지정했기 때문입니다.

 

bind는 this를 영구히 지정해주고 apply와 call은 this를 호출할 때마다 지정해주어야 합니다