대가는 결과를 만든다

call, apply, bind에 대한 정리 본문

개발/Javascript

call, apply, bind에 대한 정리

yunzema 2020. 3. 13. 17:28
반응형

함수의 메서드! 생소한 문법이었는데 정리해본다.

이전에 javascript this에 대한 이해가 먼저 선행되는게 좋다.

우리가 정의하는 함수에도 사용할 수 있는 기본 메서드가 있다는 것이다. (Array 메서드, Object 메서드 같이...)

함수의 메서드 중 call, apply, bind가 대표적이다.

 

1. call, apply


함수를 호출하는 일반적인 방법은 '함수명( )'이다. call, apply는 함수를 호출하는 또다른 방법이라고 생각하면 쉽다.

let example = function (a,b,c) {
	return a+b+c;
}

//== 아래 세개의 함수호출은 모두 똑같은 동작을 한다. ==//
example(1,2,3);
example.call(null, 1, 2, 3);
example.apply(null, [1,2,3]);

call과 apply의 차이가 있다면, call은 함수 parameter를 보통 함수와 똑같이 넣고, apply는 paramter를 하나로 묶어 배열로 전달하는 것이다.

 

call과 apply의 첫번째 parameter는 공통적으로 this를 대체하는 것이다. (이래서 this의 개념이 선행되어야한다고 한것!)

this를 대체하는 예를 보자.

let obj = {
	string : 'test',
    test: function() {
    	console.log(this.string);
    }
};

var obj2 = {
	string : 'test2'
};

obj.test();		//test를 출력
obj.test.call(obj2);	//test2를 출력

두번째 함수 호출에서 .call(obj2) 를 호출함으로써 this가 가리키는 것이 obj가 아니라 obj2로 바뀌었다.

obj의 메서드 이지만, obj2의 메서드인 것처럼 사용이 가능한 것이다.

다시 말하자면, javascript에서 this가 가리키는 것을 call(call 이외에도 위에 언급한 메서드들)을 통해 변경할 수 있고, 다른 객체의 메서드를 사용 가능하다는 것 입니다.

 

예시로 Array가 아닌 객체에서 Array함수를 쓰고 싶을 때를 살펴보자.

function example() {
	console.log(arguments);
}

example(1, 'string', true);	//[1, 'string', true]를 출력

함수는 기본적으로 함수에 들어오는 paramter를 배열형식으로 반환하는 arguments라는 숨겨진 속성을 가지고 있다. 이는 배열처럼 보이지만, 실제 배열이 아니라 유사배열이기 때문에, 배열형식이라고 표현한 것인데, 아래와 같이 Array 메서드(join)를 사용하면 Error가 발생한다. (Array가 아닌데 Array 메서드를 호출했으니까)

function example2() {
  console.log(arguments.join());
}
example2(1, 'string', true); // Uncaught TypeError: arguments.join is not a function

이런 경우에 call, bind 사용으로 Array의 메서드를 사용 가능하다. Array의 prototype에 있는 join 함수를 빌려쓰는 것이다. this가 arguments를 가리키도록 call을 사용한 것이다.

function example3() {
  console.log(Array.prototype.join.call(arguments));
}
example3(1, 'string', true); // '1,string,true'

 

2. bind


위에서 살펴본 call, apply는 실제 함수를 호출하는 메서드였다면, bind는 this가 가리키는 것을 바꾸기만 하고 호출은 하지 않은this가 바뀐 함수를 리턴하는 것이다.

let obj = {
  string: 'test',
  test: function() {
    console.log(this.string);
  }
};

let obj2 = {
  string: 'test2'
};

let test2 = obj.test.bind(obj2);	// obj.test함수의 this가 가리키는 것을 obj2로 바꾼 함수를 리턴
test2(); 				//'test2'를 출력

//아래 코드가 함수 호출 시 사용하는 것 이겠다.
obj.test.bind(obj2)();
obj.test.call(obj2);

test2를 정의 하는 거처럼 bind는 this를 변경한 후 함수를 호출하지 않고, 함수 자체를 반환한다.

 

 

참고 : https://www.zerocho.com/category/JavaScript/post/57433645a48729787807c3fd

 

Comments