call()

call()메소드를 MDN에서는 이렇게 정의하고 있다. '주어진 this값 및 각각 전달된 인수와 함께 함수를 호출한다.call이미 할당되어있는 다른 객체의 함수, 메소드를 호출하는 해당 객체에 재할당할때 사용된다. 또한 메소드를 한번 작성하면 새 객체를 위한 메소드를 재작성할 필요 없이 call()을 이용해 다른 객체에 상속할 수 있다.

 

function getName() {
	console.log(`movie's name is ${this.name}`);
}

const movie = {
	name: 'LaLaLand',
	actor: 'Ryan Gosling'
}

 

위와 같은 코드가 있을 때, movie객체에서 name을 출력하는 메소드가 필요하다고 하자. 일단 getName함수가 movie객체 안에 있지 않기 때문에 movie.getName()과 같이 호출을 할 수 없다. 이때, call()을 이용해 movie객체에 getName함수를 상속시킬 수 있다.

 

getName.call(movie); // movie's name is LaLaLand

 

위와 같이 getName을 호출하면 thismovie에 바인딩 된다. 이때, call()메소드의 첫 번째 인자에 아무런 값도 주지 않게 되면 this는 전역 객체에 바인딩된다.

 

let name = 'WhiPlash';

function getName() {
	console.log(`movie's name is ${this.name}`);
}

const movie = {
	name: 'LaLaLand',
	actor: 'Ryan Gosling'
}

getName.call(); // movie's name is WhiPlash

 

apply()

MDN에서는 apply()메소드를 다음과 같이 정의한다.  '주어진 this 값과 배열로 제공되는 arguments 로 함수를 호출한다.'  apply()call()메소드와 거의 동일하지만 한 가지 차이점이 있다. call()이 함수의 인자들을 하나씩 받는 반면, apply()는 하나의 배열을 받는다. 또한 call()과 마찬가지로 이미 존재하는 함수를 호출할 때 다른 this객체를 할당할 수 있으며 새로운 객체마다 메소드를 재작성할 필요없이 한 번만 작성해 다른 객체에 상속시킬 수 있다.

 

function getName(m1, m2, m3) {
	console.log(`His name is ${this.director}. He directed ${m1}, ${m2} and ${m3}`);
}

const movie = {
	name: 'LaLaLand',
	actor: 'Ryan Gosling',
	director: 'Damien Chazelle'
}

movies = ['LaLaLand', 'WhiPlash', 'FirstMan'];

getName.apply(movie, movies); // His name is Damien Chazelle. He directed LaLaLand, WhiPlash and FirstMan

 

위와 같이 this가 바인딩될 객체인 moviegetName의 파라미터인 m1, m2, m3에 해당하는 단일 배열 movies을 넘겨준다. apply()역시 첫 번째 인자가 null일 경우, 전역 객체를 가리킨다. 위의 예에서 call()의 경우 다음과 같이 사용할 수 있다.

 

getName.call(movie, movies[0], movies[1], movies[2]);

 

 

bind()

bind()메소드의 정의는 다음과 같다. 'bind()메소드가 호출되면 새로운 함수를 생성합니다. 받게되는 첫 인자의 value로는 this 키워드를 설정하고, 이어지는 인자들은 바인드된 함수의 인수에 제공된다.정의에서 나와 있듯이 bind()는 새로운 함수를 생성한다. call()apply()와 같이 첫 번째 인자로 this가 바인딩될 객체를 넘겨준다.

 

function getName(m1, m2, m3) {
	console.log(`His name is ${this.director}. He directed ${m1}, ${m2} and ${m3}`);
}

const movie = {
	name: 'LaLaLand',
	actor: 'Ryan Gosling',
	director: 'Damien Chazelle'
}

movies = ['LaLaLand', 'WhiPlash', 'FirstMan'];

const myFunction = getName.bind(movie, movies[0], movies[1], movies[2]);
myFunction(); // His name is Damien Chazelle. He directed LaLaLand, WhiPlash and FirstMan

 

 

앞서 설명한바와 같이, bind()는 새로운 함수를 생성하기 때문에 위와 같이 myFunction에 담아 나중에 호출할 수 있다. MDN의 예시를 하나 살펴보자.

 

this.x = 9;
let module = {
  x: 81,
  getX: function() { console.log(this.x); }
};

module.getX(); // 81

let retrieveX = module.getX;
retrieveX(); // 9

let boundGetX = retrieveX.bind(module);
boundGetX(); // 81

 

첫 번째로, module.getX()는 암시적 바인딩으로 getXthismodule에 바인딩된다. 따라서 81이 출력되는 것을 볼 수 있다. 두 번째 예로는 module객체의 getX메소드를 추출하여 retrieveX에 담고, 전역 스코프에서 retrieveX()와 같이 호출을 하였다. 이렇게 되면 일반 함수를 호출한것과 같이 this가 전역 객체를 가리키게 되므로 9를 출력한다. 세 번째는 추출한 함수에 module을 인자로 주고 명시적 바인딩을 했으므로 thismodule에 바인딩 된다. 따라서 module의 x값이 출력이 되는 것을 볼 수 있다.

 


생강강

,