생활코딩 객체 지향 프로그래밍 수업을 보며 정리한 내용입니다.
call 은 실행할 때마다 어떤 객체의 this값을 바꾸는 명령어로, 자바스크립트를 정말 유연하게 쓸 수 있도록 만들어준다.
이전까지는 객체안에 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자리에 들어갈 인자값들을 전해주는 것이다.
정리
참고
apply
가 있다.call
못지않게 독특한 게 또 있는데 그것이 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
은 실행할 때 함수의 context. 즉 this 의 값을 바꾸는 것이고 bind
는 어떤 함수에서의 내부적인 디스의 값을 영구적으로 바꾸는 새로운 함수를 만드는 것이다.