TIL 29 | JavaScript 객체 지향 프로그래밍 06

생활코딩 객체 지향 프로그래밍 수업을 보며 정리한 내용입니다.


call

call 은 실행할 때마다 어떤 객체의 this값을 바꾸는 명령어로, 자바스크립트를 정말 유연하게 쓸 수 있도록 만들어준다.

① call이란?

이전까지는 객체안에 method가 들어있었는데, 이제는 어떤 객체에도 속해있지 않는 함수를 call 을 이용해서 마치 객체 내부의 method를 이용하는것 처럼 해줄 수 있다.

const kim = { name: "kim", first: 10, second: 20 };
const lee = { name: "lee", first: 10, second: 10 };

function sum() {  //이렇게 아무 객체에도 속해 있지 않다.
  return this.first + this.second;  
}
//sum.call(); 를 해주면 되는데, sum.call()은 sum() 과 똑같은 거다.
sum.call(kim); //이렇게 첫번째 인자로 kim을 전달해주면 된다.

console.log(sum.call(kim)); //30  ..kim의 first와 second가 더해져서 30이 나왔다.

이렇게 사용해 줄 수 있는 이유는 call 이라고 하는 method는 자바스크립트의 모든 함수가 가지고 있는것이기 때문이다. (왜냐하면 자바스크립트에서는 함수도 객체니까 method를 갖고있다!)

② 첫번째 인자의 역할

call첫번째 인자에는 그 함수에서 내부적으로 사용할 this의 값을 지정해준다.

sum.call(kim);  //이 함수는 내부적으로 아래 코드의 일들이 일어나는 것이다.

function sum() {
  this = kim                           //이렇게 해주는 것과 같다.
  return this.first + this.second;
}

즉, sum이라는 함수는 kim이라는 객체의 멤버가 아니었지만 call을 이용해 함수를 호출할 때 첫번째 인자로 sum이 내부적으로 사용할 this를 kim으로 지정했기때문에
→ sum 함수가 kim 객체의 멤버인 method가 된 것이다.

🤚🏻 그럼 lee를 인자로 준다면?

console.log(sum.call(lee));  //20   ..이번엔 sum의 내부에서 이용되는 this는 lee객체가 된 것이다.

③ 두번째 이후 인자들의 역할

그리고 call 은 인자를 몇개 더 받을 수 있는데,
만약 우리가 호출하는 sum 함수에게 parameter가 있다면, 그 파라미터로 들어갈 인자값들을 전달해 준다.

function sum2(prefix) {
  return prefix + (this.first+this.second);
}

console.log(sum2.call(lee, "=> ")); // => 20

👏🏻 호출하는 sum에게 prefix라는 parameter이 있어서, 실행할 때 prefix가 출력이 되고 거기에다가 더하기한 결과가 결합되어 리턴된다면 prefix도 전달해주어야 하니까
→ 이렇게 prefix자리에 들어갈 인자값들을 전해주는 것이다.

정리

  • 첫 번째 인자로는 그 함수의 내부적으로 this를 무엇을 할 것인가가 오고
  • 두 번째 인자부터는 호출하려고 하는 함수의 파라미터로 들어갈 인자 값들이 들어온다.

참고

  • call과 유사한 것으로 apply 가 있다.



bind

call 못지않게 독특한 게 또 있는데 그것이 bind 이다.

① bind 란?

이번에는 sum이라는 함수가 호출될 때마다 this를 바꾸는 것이 아니라,
아예 함수에서 내부적으로 사용할 this를 딱 고정시켜버리는 방법이다.


② 첫번째 인자의 역할

bind 의 첫 번째 인자는 그 함수 내부적으로 this를 무엇으로 쓸것인가를 정하는것이다.

const kim = { name: "kim", first: 10, second: 20 };
const lee = { name: "lee", first: 10, second: 10 };

function sum(prefix) {
  return prefix+(this.first + this.second);  
}

const kimSum = sum.bind(kim, "==> ");
//sum이라고 하는 함수에다가, 함수는 똑같은데 내부적으로 this를 kim으로 하는 새로운 함수가 만들어진다.

→ 이렇게 해주면 이 함수는 내부적으로 this가 kim 이 되고, 뒤에 따라오는 인자(==>)가 prefix 값이 된다.

👏🏻 그럼이제 this도 지정이 되었고, prefix도 지정이 되었기 때문에 우린 이제 그냥 호출만 하면 된다. 👌🏻✨

console.log(kimSum());  //==> 30

③ 두번째 이후 인자들의 역할

그리고 bind 도 마찬가지로 그 함수가 호출될 때마다 파라미터로 사용될 인자값들을 지정해 줄 수 있다.

const kimSum = sum.bind(kim, "==> "); // ==> 이부분

🚨 만약 prefix값을 지정해주지 않는다면 전달되는 인자가 없기때문에 결과는 NaN 이 나오게 된다.

function sum(prefix) {
  return prefix + (this.first + this.second);
}

const kimSum = sum.bind(kim);
console.log(kimSum()); //NaN

🤚🏻 그렇지만 원래의 sum이 바뀌는 것은 아니다. 그냥 새로운 함수가 만들어져서 return되는 것이고 sum에는 아무런 영향을 주지 않는다.



call vs bind 🔥

  • call 은 실행할 때 함수의 context. 즉 this 의 값을 바꾸는 것이고
  • bind 는 어떤 함수에서의 내부적인 디스의 값을 영구적으로 바꾸는 새로운 함수를 만드는 것이다.

좋은 웹페이지 즐겨찾기