현재 번역은 완벽하지 않습니다. 한국어로 문서 번역에 동참해주세요.

Summary

apply() 메소드는 주어진 this값과 arguments로 함수를 호출합니다.
arguments에는 배열( 또는 유사배열객체 array-like object)가 올 수 있습니다.

Note: 이 함수의 구문은 거의 call()구문과 유사합니다., 기본적으로 다른 점은  call()은 함수에 전달될 여러 개의 인자를 받는데 비해, apply()는 배열로 된 하나의 인자를 받는다는 점입니다.

Syntax

fun.apply(thisArg, [argsArray])

Parameters

thisArg
호출될 함수에게 지정될 this의 값입니다. 호출된 함수 내에서 this가 전달된 thisArg인자와 다를 수 있으므로 주의: 만약 함수가 non-strict mode 모드에서 실행 중이라면, nullundefined 는 전역객체로 대체되고, 기본값은 레퍼객체로 대체됩니다.
argsArray
유사배열객체, 특히 함수가 호출될 때 생성된 arguments객체, 함수에 전달할 인자가 없는 경우는 null 또는 undefined. ECMAScript 5에서는 배열 대신 유사배열객체로 일괄처리 됩니다. 하단에 있는browser compatibility 참조.

Description

이미 존재하는 함수를 호출할 때 다른 this객체를 할당할 수 있습니다. this는 현재 객체로 호출한 객체를 참조합니다. apply를 이용하면 새로운 객체마다 메소드를 재작성할 필요없이 한 번만 작성해 다른 객체에 상속시킬 수 있습니다.

apply는 지원되는 인자의 타입만 제외하면 call()과 매우 유사합니다. 명명된 인자조합 대신 인자배열을 사용할 수 있습니다. apply에서는 배열리터럴이나 Array객체를 사용할 수 있는데, 예를들어 배열리터럴은 fun.apply(this, ['eat', 'bananas'])과 같은 형태로, 배열객체는 fun.apply(this, new Array('eat', 'bananas'))와 같이 사용됩니다.

argsArray인자에는 arguments도 사용할 수 있습니다. arguments는 함수의 지역변수입니다. 호출된 함수에 명시적으로 선언되지 않은 모든 인자를 위해 사용할 수 있습니다. 따라서 apply를 사용할 때 호출된 객체의 인자를 알 필요가 없습니다. arguments를 이용해 호출된 객체의 모든 인자를 전달할 수 있으며, 호출된 객체는 그 인자를 조작할 수 있게 됩니다.

ECMAScript 5판에서는 유사배열객체를 사용할 수 있으며, 구체적으로는 length속성을 갖고 0 이상 length미만 범위의 정수를 속성으로 갖는 모든 종류의 객체의 사용을 인정하고 있습니다. 예를 들면 NodeList 또는 { 'length': 2, '0': 'eat', '1': 'bananas' }과 같은 고유하게 정의된 객체를 사용할 수 있습니다.

주의: Chrome14와 Internet Explorer 9를 포함한 대부분의 브라우저느 아직 유사배열객체를 apply에 사용할 수 없으며 오류가 출력됩니다.

Examples

예: apply를 이용한 생성자 체인

apply를 이용하면 java처럼 객체에 대해 constructors 를 연결할 수 있습니다. 다음 예제에서 Function 에 construct라는 메서드를 생성하여, 인자의 목록 대신 유사배열객체를 construct와 함께 사용할 수 있게 합니다.

Function.prototype.construct = function (aArgs) {
  var oNew = Object.create(this.prototype);
  this.apply(oNew, aArgs);
  return oNew;
};

Note: 위에서 사용된 Object.create()는 비교적 새로운 것입니다. 클로저를 사용한 대체 메소드는 다음과 같습니다.

Function.prototype.construct = function(aArgs) {
  var fConstructor = this, fNewConstr = function() { fConstructor.apply(this, aArgs); };
  fNewConstr.prototype = fConstructor.prototype;
  return new fNewConstr();
};

Example usage:

function MyConstructor() {
  for (var nProp = 0; nProp < arguments.length; nProp++) {
    this['property' + nProp] = arguments[nProp];
  }
}

var myArray = [4, 'Hello world!', false];
var myInstance = MyConstructor.construct(myArray);

alert(myInstance.property1);                // alerts 'Hello world!'
alert(myInstance instanceof MyConstructor); // alerts 'true'
alert(myInstance.constructor);              // alerts 'MyConstructor'

Note: 위에 등장한 네이티브가 아닌 Function.construct메소드는 몇몇 네이티브 생성자에는 작동하지 않습니다(예를 들어 Date) 이런 경우 Function.prototype.bind 메소드를 이용해야 합니다(예를들어 Date 생성자에 사용할 [2012, 11, 4] 와 같은 배열을 가정한다면, new (Function.prototype.bind.apply(Date, [null].concat([2012, 11, 4])))() 같이 생각해볼 수 있습니다- 어쨌든 이것은 최선의 선택이라고는 할 수 없으며, 어떤 제품수준의 환경에서도 사용해서는 안 될 것입니다.

예: apply를 내장함수와 함께 사용

apply를 보다 효과적으로 이용하면 일부 내장 함수는 어떤 작업에 대해서는 배열과 루프없이 쉽게 처리됩니다. 다음 예제에서는 배열에서 최대값과 최소값을 구하기 위해 Math.max/Math.min 함수를 이용하고 있습니다.

/* min/max number in an array */
var numbers = [5, 6, 2, 3, 7];

/* using Math.min/Math.max apply */
var max = Math.max.apply(null, numbers); /* This about equal to Math.max(numbers[0], ...)
                                            or Math.max(5, 6, ...) */
var min = Math.min.apply(null, numbers);

/* vs. simple loop based algorithm */
max = -Infinity, min = +Infinity;

for (var i = 0; i < numbers.length; i++) {
  if (numbers[i] > max) {
    max = numbers[i];
  }
  if (numbers[i] < min) {
    min = numbers[i];
  }
}

하지만 이러한 방식으로 apply를 이용하는 경우 주의해야 합니다. JavaScript 엔진의 인자 길이 제한을 초과하는 위험성에 대해 이해할 필요가 있습니다. 함수에 너무 많은(대략 몇 만개 이상) 인자를 줄 때의 상황은 엔진마다 다른데(예를 들어 JavaScriptCore의 경우 인자수의 제한은 65536), 상한이 특별히 정해져 있지 않기 때문입니다. 어떤 엔진은 예외를 던집니다. 더 심한 경우는 실제 함수에 인자를 전달했음에도 불구하고 참조할 수 있는 인자의 수를 제한하고 있는 경우도 있습니다(이러한 엔진에 대해 더 자세히 설명하면, 그 엔진이 arguments의 상한을 4개로 했다고 하면[실제 상한은 물론 더 위일 것입니다], 위 예제 코드의 전체 배열이 아니라 5, 6, 2, 3만 apply에 전달되어 온 것처럼 작동합니다). 만약 사용하는 배열 변수의 수가 수만을 초과하는 경우에는 복합적인 전략을 강구해야할 것입니다:한 번에 전달할 배열을 분할하여 apply하기:

function minOfArray(arr) {
  var min = Infinity;
  var QUANTUM = 32768;

  for (var i = 0, len = arr.length; i < len; i += QUANTUM) {
    var submin = Math.min.apply(null, arr.slice(i, Math.min(i + QUANTUM, len)));
    min = Math.min(submin, min);
  }

  return min;
}

var min = minOfArray([5, 6, 2, 3, 7]);

예: "monkey-patching"에 apply사용

apply는 FireFox의 내장 함수나 JS 라이브러리에 monkey-patch를 위한 가장 좋은 방법입니다. 주어진 someobject.foo 함수를 다음과 같은 방법으로 변형합니다:

var originalfoo = someobject.foo;
someobject.foo = function() {
  // 함수가 호출되기 전에 할 일
  console.log(arguments);
  // 보통 때처럼 함수를 호출함:
  originalfoo.apply(this, arguments);
  // 함수가 호출된 후 할 일
}

이 메소드는 특히 다양한 .on([event]...Devtools Inspector에서 사용할 수 있는 event)과 같은 API가 없는 객체의 이벤트나 인터페이스를 디버깅할 때 유용합니다.

Specifications

Specification Status Comment
ECMAScript 3rd Edition. Standard Initial definition. Implemented in JavaScript 1.3.
ECMAScript 5.1 (ECMA-262)
The definition of 'Function.prototype.apply' in that specification.
Standard  
ECMAScript 2015 (6th Edition, ECMA-262)
The definition of 'Function.prototype.apply' in that specification.
Standard  

Browser compatibility

We're converting our compatibility data into a machine-readable JSON format. This compatibility table still uses the old format, because we haven't yet converted the data it contains. Find out how you can help!

Feature Chrome Firefox (Gecko) Internet Explorer Opera Safari
Basic support (Yes) (Yes) (Yes) (Yes) (Yes)
ES 5.1 generic array-like object as arguments ? 4.0 (2.0) ? ? ?
Feature Android Chrome for Android Firefox Mobile (Gecko) IE Mobile Opera Mobile Safari Mobile
Basic support (Yes) (Yes) (Yes) (Yes) (Yes) (Yes)
ES 5.1 generic array-like object as arguments ? ? 4.0 (2.0) ? ? ?

See also

문서 태그 및 공헌자

이 페이지의 공헌자: bsidesoft
최종 변경: bsidesoft,