⚙️ 리얼포스 R3 45g 텐키리스로 키보드로 썼읍니다..
📌
call
,apply
,bind
는 자바스크립트에서 함수의 호출 방식과 관계없이 this를 지정할 수 있다.
call
메소드는 모든 함수에서 사용할 수 있고, this를 특정값으로 지정할 수 있다.const Joonyoung = {
name: 'Joonyoung',
}'
function showName(){
console.log(this.name);
};
showName(); // 출력결과가 없습니다.
위의 코드와 같이 this.name
을 호출하는 함수의 출력결과가 아무것도 없는데, 이유는 여기서의 this
는 window
를 가리키기 때문이다.
window.name
이 빈문자열이기 때문이다.showName.call(Joonyoung) // "Joonyoung"
이때 showName
에 call
을 해주고 Joonyoung
을 전달해 준다면, 우리가 원하는 결과가 출력이된다.
여기서 call
의 첫번째 매개변수는 this
로 사용 할 값이고, 매개변수가 더 있다면, 그 매개변수로 호출하는 함수로 전달이 된다.
const Joonyoung = {
name: 'Joonyoung',
}'
// 생년,월을 받아서 this 객체의 값을 업데이트 하는 함수
function updateObject(birthYear, birthMonth){
this.birthYear = birthYear;
this.birthMonth = birthMonth;
};
updateObject.call(Joonyoung, 1997, 7);
console.log(Joonyoung);
// { name: "Joonyoung", birthYear: 1997, birthMonth: 7 }
첫번째 매개변수로는 this
로 사용 될 값이고, 이후의 매개변수는 함수가 사용 할 매개변수를 순서대로 준 것이다.
apply
는 함수의 매개변수를 처리하는 방법을 제외하면 call
과 같다.
call
은 일반적인 함수와 마찬가지로 매개변수를 직접 받지만, apply
는 매개변수를 배열로 받는다.
방금 call
에서 사용했던 예제를 apply
로 바꿔준다면...
const Joonyoung = {
name: 'Joonyoung',
}'
// 생년,월을 받아서 this 객체의 값을 업데이트 하는 함수
function updateObject(birthYear, birthMonth){
this.birthYear = birthYear;
this.birthMonth = birthMonth;
};
updateObject.apply(Joonyoung, [1997, 7]);
console.log(Joonyoung);
// { name: "Joonyoung", birthYear: 1997, birthMonth: 7 }
매개변수를 배열로만 바꿔주면 끝이다!!
🤨 그렇다면 여기서 의문점이 드는데, 이걸 언제 써야 유용한걸까?
apply는 배열요소를 함수 매개변수로 사용할때 유용하다.
다음과 같이 배열이 주어지고 최솟값을 구해야한다고 가정해보자
const nums = [2, 6, 1, 7, 10];
const min = Math.min(nums);
console.log(min); // NaN
배열자체를 넣어버려서 결과가 NaN
으로 나온다.
하지만 nums
는 배열이니까 apply
를 활용한다면...
const nums = [2, 6, 1, 7, 10];
const min = Math.min.apply(null, nums);
console.log(min); // 1
apply
는 두번쩨 매개변수로 배열을 전달하면 그 요소를 차례대로 인수로 전달한다.
따라서 위에 코드와 같이 해주면 결과가 정상적으로 출력되는 것을 볼 수 있다.
앞의 null
은 this
로 사용 될 값인데, 딱히 필요해 보이지 않아서 아무값이나 넣어준 것이다.
함수의 this
값을 영구히 바꿀 수 있다.
한번더 call
에서 쓰던 예제를 돌려먹기로 bind
를 활용해보려고 한다.
const Joonyoung = {
name: 'Joonyoung',
}'
// 생년,월을 받아서 this 객체의 값을 업데이트 하는 함수
function updateObject(birthYear, birthMonth){
this.birthYear = birthYear;
this.birthMonth = birthMonth;
};
const justJoonyoung = updateObject.bind(Joonyoung);
justJoonyoung(1997, 7);
console.log(Joonyoung);
// { name: "Joonyoung", birthYear: 1997, birthMonth: 7 }
bind
로 새로운 함수를 만들었다. justJoonyoung
함수는 항상 this
로 Joonyoung
을 바라보게 된 것이다.
새로운 유저 객체를 만들고, 객체안에 이름을 출력하는 함수를 만들어서 실행시켜보았다.
const user = {
name: "Joonyoung",
showName: function(){
console.log("cool" + this.name);
},
};
user.showName(); // "cool Joonyoung"
결과가 잘 나오는 모습을 볼 수 있다.
하지만 여기서 user.showName()을 새로운 변수에 할당해서 실행한다면 결과가 어떨까?
const anotherFunc = user.showName();
anotherFunc(); // "cool"
...내이름은 어디로 사라진걸까?
anotherFunc
에 할당 할 때this
를 잃어버린 것인데, 메소드는user.showName
처럼.
앞에 있는게this
가 되는데, 호출할 때anotherFunc
만 호출하게 되니까this
가 없는것이다!
이러한 경우에 bind
를 사용하면 손쉽게 해결 할 수 있다.
const anotherFunc = user.showName();
const anotherAnotherFunc = anotherFunc.bind(user);
anotherAnotherFunc(); // "cool Joonyoung"