본문으로 바로가기

[JavaScript] call, apply, bind - this 친구들

이전 게시글에서 this를 알아보았습니다. this를 학습한 후 all, apply, bind 까지 공부해두면 좋을 것 같아서 정리해보았습니다. 참고로 bind의 경우 저번 게시글에서 다루어 셜명이 매우 간단합니다. 더 자세한 내용은 이전 게시글을 참고해주세요. 이전 게시글

call, apply, bind

■ call

call에 대해 먼저 알아보겠습니다.

func.call(thisArg[, arg1[, arg2[, ...]]])

call 함수는 위와 같이 생겼습니다. call 함수가 하는 역할은 this를 내가 원하는 것으로 지정하는 것입니다. thisArg에 this로 지정하고 싶은 값을 넘기면 됩니다. 추가적인 매개변수를 넘기고 싶으면 뒤에 comma(,)로 이어 붙이면 됩니다. 하나씩 예시를 통해 알아봅시다.

우선 간단하게 아래 코드를 보고 this에는 어떠한 값이 나올 지 생각해봅시다.

const apple = {
  name: "사과"
};

const banana = {
  name: "바나나"
};

function whatIsThis() {
  console.log(this);
}

어떠한 값이 나올까요? 혹시 정답이 틀렸거나 생각이 나지 않으면 이전 게시글(this)에 대해 보고 오는 것을 추천드립니다. global에서 함수를 실행하고 있죠. 정답은 global 객체입니다.

그럼 이제 call을 사용하여 this를 내가 원하는 것으로 지정해보겠습니다. 각각 apple, banana 객체로 this를 지정하는 코드입니다.

const apple = {
  name: "사과"
};

const banana = {
  name: "바나나"
};

function whatIsThis() {
  console.log(this);
}

whatIsThis.call(apple);
whatIsThis.call(banana);

call 함수 첫번째 인자 값으로 apple, banana를 넘겨준 결과 해당 객체가 this로 잘 출력이 되는 것을 확인할 수 있습니다.

call 함수를 사용하면서 this 뿐만이 아니라 특정 값을 추가로 넘겨주어 update나 remove 등 다른 추가적인 작업을 하고 싶을 수 있습니다. 이러한 경우 어떻게 할까요? args로 넘겨주면 됩니다. 위에서 말씀드렸듯이 comma(,)로 이어 붙이면 됩니다.

const apple = {
  name: "사과"
};

const banana = {
  name: "바나나"
};

function whatIsThis() {
  console.log(this);
}

function update(color, price) {
  this.color = color;
  this.price = price;
}

whatIsThis.call(apple);
whatIsThis.call(banana);

update.call(apple, "red", 1000);
update.call(banana, "yellow", 2000);

whatIsThis.call(apple);
whatIsThis.call(banana);

위 코드는 args로 color, price를 넘겨주고 있습니다. 그리고 update 함수에서 this에 해당 값으로 업데이트 하고 있습니다. 결과를 확인해봅시다.

우리가 생각한 대로 각 apple, banana 객체에 color와 price가 추가된 것을 확인할 수 있습니다. 이 개념을 바탕으로 필요없는 key값을 삭제하는 remove 함수도 구현해봅시다.

const apple = {
  name: "사과",
  price: 1000
};

const banana = {
  name: "바나나",
  price: 2000
};

function whatIsThis() {
  console.log(this);
}

function remove(type) {
  delete this[type];
}

whatIsThis.call(apple);
whatIsThis.call(banana);

remove.call(apple, "price");
remove.call(banana, "name");

whatIsThis.call(apple);
whatIsThis.call(banana);

바로 결과를 확인해봅시다.

역시 우리가 원하는대로 apple 객체에서는 price, banana 객체에서는 name이 삭제되었습니다.

■ apply

apply는 무엇일까요? apply도 call가 동일하게 this를 지정해주는 함수입니다. 그러나 call과 다른 것이 있습니다. 아래 코드를 확인해봅시다.

func.apply(thisArg, [argsArray])

다른 것은 1개, args를 넘기는 방법입니다. call에서는 args를 comma(,)로 넘겨주었다면 apply는 array로 넘겨줍니다. apply 예제로 많이 사용되는 최대값, 최소값 찾기를 구현해봅시다.

const numbers = [5, 1, 2, 3, 8];
const max = Math.max.apply(null, numbers);
const min = Math.min.apply(null, numbers);

console.log("max", max);
console.log("min", min);

위 코드가 바로 이해가 되시나요? apply로 this는 null, args는 numbers를 넘겨주어 max, min 값을 구하였습니다. this의 경우 max, min 값을 구하는 데 필요 없기 때문에 null 값을 넘겨주었습니다. 간단하여 쉽게 이해하셨을 것입니다. 그럼 더 직관적으로 call 함수와의 차이를 보기 위해 call 함수로도 구현해보겠습니다.

const numbers = [5, 1, 2, 3, 8];

const applyMax = Math.max.apply(null, numbers);
const callMax = Math.max.call(null, ...numbers);

const applyMin = Math.min.apply(null, numbers);
const callMin = Math.min.call(null, ...numbers);

console.log("applyMax", applyMax);
console.log("callMax", callMax);

console.log("applyMin", applyMin);
console.log("callMin", callMin);

결과 이미지를 보시면 알 수 있듯이 동일합니다. 그러나 코드를 보시면 call의 경우 ...(spread) 문법을 통해 풀어서 args를 넘겨주었습니다.

■ bind

bind의 경우 이전 게시글에서도 설명하였으니 예시 코드는 생략하겠습니다. 우선 bind 함수도 어떻게 생겼는 지 확인해봅시다.

func.bind(thisArg[, arg1[, arg2[, ...]]])

bind 함수도 위 함수들과 다를 게 없이 비슷하게 생겼습니다. this를 1번째 인자로 받고 뒤 이어서 comma(,)로 args를 받습니다. bind도 위 함수들과 같이 this를 지정해주는 것입니다.

■ 정리

정리하자면 call, apply, bind 모두 this를 지정해주는 것입니다. call과 apply는 동일하지만 args를 다루는 방법이 다릅니다. 자 그렇다면 call이랑 bind랑은 같지 않는가? 라고 생각할 수 있습니다. 결론은 아시다 싶이 다르니깐 2개가 있는 것이겠죠? call(+ apply)은 바로 실행을 하지만 bind는 연결만 해두는 것입니다. 실행은 하지 않는 다는 것이죠. 실행은 내가 원할 때 하겠다는 것이죠. 이것이 큰 차이입니다. 이해가 되셨을까요?

참고자료

마지막

해당 내용은 틀릴 수도 있다는 것을 감안하여 봐주세요. 틀린 내용 및 오탈자 수정 요청 환영입니다.

반응형