[JS] 자바스크립트 중급강좌 (feat. 코딩앙마) - call, apply, bind

1. call

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

const mike = {
	name: 'Mike'  
}
const tom = {
	name: 'Tom'  
}
function showThisName() {
	console.log(this.name);   // 여기서의 this는 window를 가리킴.  
}

showThisName();   // ""
showThisName.call(mike);   // Mike -> function에서 this가 mike가 된 것.
showThisName.call(tom);   // Tom

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 }

함수가 매개변수를 받는 형태라면 call 메서드에 this로 사용할 객체와 이 후 사용할 매개변수의 값을 넣어준다.

2. apply

apply는 함수 매개변수를 처리하는 방법을 제외하면 call과 완전히 같다. call은 일반적인 함수와 마찬가지로 매개변수를 직접 받지만 apply는 매개변수를 배열로 받는다.

위의 코드를 call에서 apply로 바꾸게 되면 다음과 같다.

update.apply(mike, [1999, 'singer']);
update.apply(tom, [2003, 'teacher']);

예제 하나를 살펴보자.

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

console.log(minNum, maxNum);   // NaN, NaN

위의 상황 같은 경우에는 Math의 min과 max는 배열이 아닌 형태로 넣어줘야 값이 잘 출력된다. 따라서 스프레드 전개구문을 사용하면 간편하다.

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

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

다음과 같이 작성하면 잘 출력되는 것을 볼 수 있다. 이렇게도 작성할 수 있지만 apply를 사용해서도 가능하다.

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

const minNum = Math.min.apply(null, nums);
const maxNum = Math.max.apply(null, nums);

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

apply 메서드에서 this로 지정할 객체를 null로 한 이유는 Math 메서드를 사용하기 때문에 딱히 필요가 없기 때문이다.

또한 위의 코드에서 call도 사용하고 싶을 경우에는 스프레드 구문을 사용하면 될 것이다. (Math.min.apply(null, ...nums))

3. bind

bind는 함수의 this 값을 영구히 바꿀 수 있다.

const mike = {
	name: 'Mike'  
}
function update(birthYear, occupation) {
	this.birthYear = birthYear;
  	this.occupation = occupation;
}

const updateMike = update.bind(mike);   // 이 함수는 mike를 항상 this로 받는다.

updateMike(1980, 'police');   // { name: Mike, birthYear: 1980, occu: police }

bind를 사용해서 mike를 항상 this로 받게 했다. 이제 실제 예제를 살펴보자.

const user = {
	name: 'Mike',
  	showName: function () {
    	console.log(`hello, ${this.name}`);  
    }
};

user.showName();   // hello, Mike

let fn = user.showName();
fn();  // hello, 

위와 같이 fn을 할당할 때 this를 잃어버리게 된다.
(메소드는 점 앞에 있는 게 this이다)

이 때 call, apply, bind를 사용해서 해결이 가능하다.

let fn = user.showName();

fn.call(user);   // hello, Mike
fn.apply(user);   // hello, Mike

let boundFn = fn.bind(user);
boundFn();   // hello, Mike

(해당 포스팅의 내용은 유튜브 코딩앙마님의 영상을 참고했습니다)
Youtube: https://www.youtube.com/watch?v=4_WLS9Lj6n4

좋은 웹페이지 즐겨찾기