
call() 메서드는 모든 함수에서 사용할 수 있으며, this를 특정값으로 지정할 수 있다.
📝 참고: JavaScript에서 함수는 객체처럼 동작하므로 call()이나 apply() 메서드를 사용할 수 있다.
const mike = {
name: "Mike",
};
dd
const tom = {
name: "Tom",
};
function showThisName() {
console.log(this.name);
}
showThisName(); // "" (빈 문자열)
showThisName.call(mike); // "Mike"
showThisName.call(tom); // "Tom"
this에 아무 것도 지정하지 않은 경우 window 객체를 가리킨다. 반면, call() 메서드를 사용하면 인자로 this로 사용할 객체를 지정할 수 있다.
const mike = {
name: "Mike",
};
const tom = {
name: "Tom",
};
function showThisName() {
console.log(this.name);
}
function update(birthYear, occupation) {
this.birthYear = birthYear;
this.occupation = occupation;
};
update.call(mike, 1999, "singer");
console.log(mike); // {name:"Mike", birthYear: 1999, occupation: "singer"}
update.call(tom, 2002, "teacher");
console.log(tom); // {name:"Tom", birthYear: 2002, occupation: "teacher"}
call() 메서드의 첫 번째 매개변수는 this로 사용할 객체이다. 두 번째 매개변수부터는 함수가 사용할 매개변수이다.
apply() 메서드는 매개변수를 처리하는 방법을 제외하면 call() 메서드와 같다. call()은 일반적인 함수와 마찬가지로 매개변수를 순서대로 직접 받는다. 반면, apply() 메서드는 매개변수를 배열로 받는다.
const mike = {
name: "Mike",
};
const tom = {
name: "Tom",
};
function showThisName() {
console.log(this.name);
}
function update(birthYear, occupation) {
this.birthYear = birthYear;
this.occupation = occupation;
};
update.apply(mike, [1999, "singer"]);
console.log(mike); // {name:"Mike", birthYear: 1999, occupation: "singer"}
update.apply(tom, [2002, "teacher"]);
console.log(tom); // {name:"Tom", birthYear: 2002, occupation: "teacher"}
배열의 요소를 함수의 매개변수로 사용할 때 유용하다.
const nums = [3, 10, 1, 6, 4];
const minNum = Math.min(nums); // NaN
const minNum = Math.min(...nums);
const maxNum = Math.max(...nums);
console.log(minNum); // 1
console.log(maxNum); // 10
min() 혹은 max() 메서드의 인자로 배열 자체를 넣으면 NaN이 출력된다.
const nums = [3, 10, 1, 6, 4];
const minNum = Math.min.apply(null, nums); // Math.min.apply(null, [3, 10, 1, 6, 4])
const maxNum = Math.max.apply(null, nums);
// Math.max.apply(null, [3, 10, 1, 6, 4])
const maxNum = Math.max.call(null, ...nums);
// Math.max.call(null, 3, 10, 1, 6, 4)
console.log(minNum); // 1
console.log(maxNum); // 10
apply() 메서드는 두 번째 매개변수로 배열을 전달하면, 배열의 요소들을 차례대로 인수로 사용한다. 이처럼, this 값을 지정하는데 쓰일 뿐 아니라, 배열의 요소를 개별 인수로 넘기는 데에도 자주 쓰인다. Math.min() 과 Math.max() 메서드는 this를 필요로 하지 않는다. 따라서 첫 번째 매개변수에는 아무 값이나 넣어도 상관없다.
함수의 this 값을 영구히 바꿀 수 있다. 다시 말해, 함수의 this 값을 고정한 새로운 함수를 반환한다. 따라서 중요한 점은 bind() 메서드는 원본 함수의 this 값을 변경하지 않고, 바운드 함수의this 값을 고정하는 것이다.
📝 참고: 바운드 함수란(Bound Function), bind() 메서드를 사용해 생성된 함수로 this 값이 고정된 함수를 말한다.
const mike = {
name: "Mike",
};
function update(birthYear, occupation) {
this.birthYear = birthYear;
this.occupation = occupation;
};
const updateMike = update.bind(mike);
updateMike(1980, "police");
console.log(mike); // {name:"Mike", birthYear: 1980, occupation: "police"}
updateMike 변수는 this가 mike를 가리키는 update 함수의 새로운 함수다.
📝 참고: const updateMike = update;라고 한다면 이는 updateMike 함수 표현식이다. 다시 말해, updateMike 변수와 update 변수는 동일한 함수 객체를 가리킨다. 따라서 updateMike(1990, "police"); 이렇게 사용할 수 있다.
updateMike = null; // updateMike는 더 이상 함수 객체를 참조하지 않음.
console.log(update); // 여전히 함수 출력. 함수 객체의 주소를 출력하는 것이 아님.
const user = {
name: "Mike",
showName: function() {
console.log(`hello, ${this.name}`);
},
};
user.showName(); // hello, Mike
let fn = user.showName; // fn에 할당할 때, this 값을 잃어버림.
fn(); // hello, 메서드 내에서 사용된 this는 해당 메서드를 호출한 객체를 가리킨다.
fn.call(user); // hello, Mike
fn.apply(user); // hello, Mike
let boundFn = fn.bind(user);
boundFn(); // hello, Mike