ES6 - call, apply, bind

marafo·2020년 9월 19일
0

✻ 개요

함수를 어디서 어떻게 호출했는지에 관계 없이 this를 지정할 수 있는 call, apply, bind에 대해 짚고 넘어간다.

( 1 ) call

const bruce = { name : "Bruce" };
const madeline = { name : "Madeline" };

function greet(){
  return `Hello, I'm ${this.name}! `;
}

greet(); // "Hello, I'm undefined!"
	 // this에 연결되는 파라미터가 없어서 어디에도 바인딩 안됨
greet.call(bruce); // "Hello, I'm bruce!" this는 bruce
greet.call(madeline); // "Hello, I'm Madeline!" this는 madeline

모든 함수에서 사용 가능하며 this를 특정 값으로 지정한다. 함수를 호출하면서 call을 마치 어떠한 객체의 메서드인 것처럼 사용할 수 있고 call의 첫 번째 파라미터가 this가 된다. 복수의 매개변수는 그대로 함수에 전달된다.

const bruce = { name : "Bruce" };
const madeline = { name : "Madeline" };

function update(birthYear, occupation){
  this.birthYear = birthYear;
  this.occupation = occupation;
}

update.call(bruce, 1949, 'singer');
update.call(madeline, 1942, 'actress');

update함수에서 call을 통해 name, birthYear, occupation이 지정된다.

( 2 ) apply

const bruce = { name : "Bruce"};
const madeline = { name: "Madeline"};

function update(name, birthYear, occupation){
  this.birthYear = birthYear;
  this.occupation = occupation;
}

update.apply(bruce, [1949, 'singer']);
// bruce = { name: "Bruce", birthYear: 1949, occpupation: "singer"}
update.apply(madeline, [1942, 'actress']);
// madeline = { name: "Madeline", birthYear: 1942, occpupation: "actress"}

call과 아주 유사하고, 두 번째 파라미터부터 마지막까지는 하나의 배열로 묶어서 받는다.

배열의 최대 최소를 구할 때 apply를 활용할 수 있다.

const arr = [2, 3, -5, 15, 7];
Math.min.apply(null, arr); // -5
Math.max.apply(null, arr); // 15

Math.min(...arr);
Math.max(...arr);
// 확산 연산자(...)을 쓰면 조금 더 간결해진다.

주어진 배열을 확산 연산자로 apply에 전달할 수 있다.

const bruce = { name : "Bruce"};
const newBruce = [ 1940, "material artist"];

function update(name, birthYear, occupation){
  this.birthYear = birthYear;
  this.occupation = occupation;
};

update.call(bruce, ...newBruce);

( 3 ) bind

const bruce = { name: "Bruce" };
const updateBruce = update.bind(bruce);

function updateBruce(name, birthYear, occupation){
  this.birthYear = birthYear;
  this.occupation = occupation;
};

updateBruce(1904, "actor");
// bruce = { name: "Bruce", birthYear: 1904, occupation:"actor"
updateBruce.call("madeline", 1274, "king");
// bruce = { name: "Bruce", birthYear: 1274, occupation:"king"

한 번 bind로 this를 묶고 나면 영구적 값이 된다. call, apply를 통해 유동적으로 this값을 변경해야 하는 경우엔 bind가 에러를 일으킬 가능성이 있다. 따라서 this가 어디에 묶이는지 확실하게 체크해야 한다.

profile
프론트 개발자 준비

0개의 댓글