본문 바로가기

Language/Javascript

[Javascript] call, apply, bind

728x90
반응형

함수 호출 방식과 관계없이 this를 지정할 수 있는 call, apply, bind 메서드에 대해 알아보자.

call

call 메서드는 모든 함수에서 사용할 수 있으며, this를 특정값으로 지정할 수 있다.

 

const mike = {
    name : "Mike",
};

const tom = {
    name : "Tom",
};

function showThisName(){
    console.log(this.name);
}

showThisName();  // ?

showThisName 메서드를 호출했을 때 아무것도 뜨지 않는다. 여기에서 this는 window를 가리킨다. window.name이 빈 문자열이기 때문에 아무것도 뜨지 않는 것이다.

 

showThisName.call(mike);  // Mike
showThisName.call(tom);  // Tom

함수를 호출하면서 call을 사용하고, this로 사용할 객체를 넘기면 해당 함수가 주어진 객체의 메소드인 것처럼 사용할 수 있다.

 

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"}

첫 번째 매개변수는 this로 사용할 값이고, 매개변수가 더 있으면 그 매개변수를 호출하는 함수로 전달된다.

apply

apply는 함수 매개변수를 처리하는 방법을 제외하면 call과 같다.

call은 일반적인 함수와 마찬가지로 매개변수를 직접 받지만, apply는 매개변수를 배열로 받는다.

 

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에서 썼던 코드에서 매개변수만 배열로 바꿔주면 같은 결과가 나오는 것을 확인할 수 있다.

 

const nums = [3, 10, 1, 6, 4];
// const minNum = Math.min(...nums);
// const maxNum = Math.max(...nums);

const minNum = Math.min.apply(null, nums);
// = Math.min.apply(null, [3, 10, 1, 6, 4])

const maxNum = Math.max.call(null, ...nums);
// = Math.min.apply(null, 3, 10, 1, 6, 4)

console.log(minNum);  // 1
console.log(maxNum);  // 10

apply는 배열 요소를 함수의 매개변수로 사용할 때 유리하다. 

Math.min이나 Math.max 메소드는 this가 필요하지 않아서 첫 번째 매개변수에는 아무 값이나 넣어도 된다.

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"}
728x90
반응형