함수의 apply(), call() 메서드

From. 프론트엔드 개발자를 위한 자바스크립트 프로그래밍

함수에는 apply()와 call() 두 가지 메서드가 더 있습니다. 이들 메서드는 모두 소유자인 함수를 호출하면서 this를 넘기는데, 결과적으로는 함수 내부에서 this 객체의 값을 바꾸는 것이나 마찬가지입니다. apply() 메서드는 매개변수로 소유자 함수에 넘길 this와 매개변수 배열으로 받습니다. 두 번째 매개변수는 Array의 인스턴스일 수도 있고 arguement 객체일 수도 있습니다. 다음 예제를 보십시오.

							function sum(num1, num2) {
								return num1 + num2;
							}

							function callSum1(num1, num2) {
								return sum.apply(this, arguments);	// arguments 객체를 넘깁니다.
							}

							function callSum2(num1, num2) {	// 배열을 넘깁니다. 
								return sum.apply(this, [num1, num2]);
							}

							alert(callSum1(10, 10));	// 20
							alert(callSum2(10, 10));	// 20							
						

이 예제에서 callSum1()은 sum()을 호출하면서 자신의 this와 arguments 객체를 매개변수로 넘겼습니다. callSum2() 역시 sum()을 호출하지만 이번에는 arguments 객체가 아니라 매배변수 배열을 넘겼습니다. 두 함수 모두 올바르게 실행됩니다.

call() 메서드도 apply()와 마찬가지로 동작하지만 매개변수를 전달하는 방식이 다릅니다. this가 첫 번째 매개변수인 점은 똑같지만 call()을 사용할 때는 반드시 다음 예제와 같이 매개변수를 각각 나열해야 합니다.

							function sum(num1, num2) {
								return num1 + num2;
							}

							function callSum(num1, num2) {
								return sum.call(this, num1, num2);
							}

							alert(callSum(10, 10));	// 20					
						

결과는 apply()와 마찬가지입니다. apply()와 call() 중 어느 쪽을 쓸지는 순전히 개발자의 재량이며 매개변수를 전달하기 편리한 방식으로 택하면 됩니다. arguments 객체를 그대로 전달해도 되거나 매개변수로 전달할 데이터가 이미 배열 형태로 준비되어 있다면 apply()가 나을 것이고, 그렇지 않다면 call()이 더 나을 겁니다. 전달할 매개변수가 없다면 두 메서드는 완진히 똑같습니다.

물론 apply()와 call()의 진가는 매개변수를 전달해 호출하는 것이 아니라 this를 바꾸는데 있습니다. 다음 예제를 보십시오.

							window.color = "red";
							var o = {color: "blue"};

							function sayColor() {
								alert(this.color);
							}

							sayColor();	// red

							sayColor.call(this);	// red
							sayColor.call(window);	// red
							sayColor.call(o)	// blue				
						

이 예제는 this 객체를 설명할 때 썼던 예제를 조금 고친 겁니다. 이번에도 sayColor()는 전역 함수로 정의되었으므로 전역 스코프에서 호출하면 this.color를 window.color로 평가하여 "red"를 표시합니다. sayColor.call(this)나 sayColor.call(window)와 같이 호출하면 함수 컨텍스트를 명시적으로 전역 스코프로 지정하는 것인데 이렇게 해도 마찬가지로 "red"를 표시합니다. 반면 sayColor.call(o)는 함수의 컨텍스트를 o로 설정하므로 "blue"를 표시합니다.

call()이나 apply()를 써서 스코프를 바꾸면 객체마다 일일히 메서드를 등록하지 않아도 된다는 장점이 있습니다. this 객체를 설명할 때는 o 객체에 직접 sayColor() 메서드를 등록했었지만 이번에는 그렇게 하지 않았습니다.

ECMAScript 5판의 함수에는 bind()라는 메서드도 정의되었습니다. 이 메서드는 새 함수 인스턴스를 만드는데 그 this는 bind()에 전달된 값입니다. 예를 들어 다음 코드를 보십시오.

							window.color = "red";
							var o = {color: "blue"};

							function sayColor() {
								alert(this.color);
							}

							var objectSayColor = sayColor.bind(o);
							objectSayColor();		// blue	
						

이 예제에서는 sayColor()에서 bind()를 호출하면서 객체 o를 넘겨 objectSayColor()라는 함수를 생성했습니다. objectSayColor() 함수의 this는 o에 묶이므로 전역에서 함수르 호출하더라도 항상 "blue"를 표시합니다.