Die apply() Methode ruft eine Funktion mit gegebenem this Wert und arguments als Array (oder einem Array ähnlichem Objekt).

Hinweis: Die Syntax dieser Funktion ist größtenteils identisch zu der Funktion call(). Der fundamentale Unterschied ist, dass call() eine Liste von Argumenten und apply() ein Array mit Argumenten übergeben bekommt.

Syntax

func.apply(thisArg, [argsArray])

Parameter

thisArg
Optional. Der Wert von this, der für den Aufruf der Funktion func genutzt wird. Zu beachten ist, dass this möglicherweise nicht der Wert ist, den die Methode sieht: Wenn die Methode eine Funktion im non-strict mode ist, werden null und undefined mit dem globalen Objekt ersetzt und primitive Werte werden in ein Hüllobjekt umgewandelt.
argsArray
Optional. Ein Array ähnliches Objekt, welches die Argumente spezifiziert, welche beim Aufruf von func benutzt werden, oder null oder undefined, wenn keine Argumente übergeben werden. Mit Einführung von ECMAScript 5 können diese Argumente mit einem generische Array ähnliches Objekt statt einem Array übergeben werden. Für mehr Informationen sollte die Browserkompatibilität geprüft werden.

Rückgabewert

Das Ergebnis der aufgerufenen Funktion mit dem spezifischen this Wert und Parametern.

Beschreibung

Man kann ein anderes this Objekt für den Aufruf einer existierenden Funktion zuweisen. this referenziert zum aktuellen Objekte, dem aufrufenden Objekt. Mit apply kann eine Methode geschrieben und in einem anderen Objekt vererbt werden, ohne die Methode für das neue Objekte neu zu schreiben.

apply ist sehr ähnlich zu call(), mit der Ausnahme des Typen der übergebenen Argumente. Man kann ein Array von Argumenten statt einer Menge von benannten Parametern benutzen. Mit apply kann man ein Arrayliteral benutzen, wie zum Beispiel fun.apply(this, ['eat', 'bananas']) oder ein Array Objekt, wie zum Beispiel fun.apply(this, new Array('eat', 'bananas')).

Für den argsArray Parameter kann auch arguments eingesetzt werden. arguments ist eine lokale Variable einer Funktion. Sie kann für alle nicht spezifizieren Argumente bei einem Aufruf benutzt werde. Dadurch muss man die Argumente eines Aufrufers nicht kennen, wenn die apply Methode genutzt wird. Man kann arguments nutzen, um alle Argumente eines Aufrufers zu übergeben. Das aufgerufene Objekt ist dann verantwortlich für das Verarbeiten der Argument.

Seit ECMAScript in der 5. Ausgabe kann jedes Objekt übergeben werden, welches Array ähnlich ist, was in der Praxis bedeutet, dass es eine length Eigenschaft hat und Ganzzahlige Eigenschaften im Bereich von 0 bis length-1 besitzt. Zum Beispiel kann man NodeList oder benutzerdefinierte Objekte wie { 'length': 2, '0': 'eat', '1': 'bananas' } benutzen.

Viele Browser, auch Chrome 14 und Internet Explorer 9, unterstützen keine Array ähnlichen Objekte, was zu einem Fehler führt.

Beispiele

apply für das Verketten von Konstruktoren verwenden

Man kann apply einsetzen, um Konstruktoren für ein Objekt zu verketten, ähnlich wie in Java. Im folgenden Beispiel wird eine globale Function Methode namens construct erstellt, welche es ermöglicht ein Array ähnliches Objekt mit einem Konstruktor anstatt eines Argumentliste zu benutzen.

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

Hinweis: Die oben eingesetzte Object.create() Methode ist relativ neu. Alternativ kann eine der folgenden Ansätze verwendet werden:

Einsatz von Object.__proto__:

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

Einsatz von Closures:

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

Einsatz von Function Konstruktoren:

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

Beispiel für den Einsatz:

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);

console.log(myInstance.property1);                // logs 'Hello world!'
console.log(myInstance instanceof MyConstructor); // logs 'true'
console.log(myInstance.constructor);              // logs 'MyConstructor'

Hinweis: Diese nicht native Function.construct Methode funktioniert nicht mit einigen nativen Konstruktoren (mit Date zum Beispiel). In diesem Fall muss man die Function.prototype.bind Methode (hat man zum Beispiel ein Array ähnliches Objekt wie folgt, um mit dem Date Konstruktor [2012, 11, 4] einzusetzen; in diesem Fall muss folgendes geschrieben werden: new (Function.prototype.bind.apply(Date, [null].concat([2012, 11, 4])))() — Jedoch ist das nicht die beste Art und Weise Probleme zu Lösen, weshalb diese Lösung nicht Praxistauglich ist).

Einsatz von apply und eingebauten Standardfunktionen

Der clevere Einsatz von apply erlaubt es standard Functionen für Aufgaben zu benutzen, für die man sonst schleifen Schreiben müsste, um über alle Elemente eines Arrays zu iterieren. Im folgenden Beispiel wurde Math.max/Math.min benutzt, um das maximalen/minimalen Wert in einem Array zu finden.

// 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];
  }
}

Jedoch muss man bei einem solchen Einsatz von apply vorsichtig sein, weil das Risiko da ist, dass man in das Limit der maximalen Argumente der JavaScriptumgebung überschreitet. Die Konsequenz aus dem ausführen von Funktionen mit zu vielen Argumenten (mehr als Zehntausend Argumente) ist, dass dieses Limit stark variiert (JavaScriptCore hat ein hart Codiertes Argumentlimit von 65536), weil es in JavaScript nicht spezifiziert ist (tatsächlich sogar die Art eines übermäßig großen Stack-Verhaltens). Einige Umgebungen erzeugen einen Fehler. Andere übergeben nicht alle Argumente der Funktion, um das Limit nicht zu überschreiten. Um diesen Fall man zu schildern: Wenn eine Umgebung ein Limit von 4 Argumenten hätte (aktuelle Limits sind natürlich signifikant höher), würde es so sein, als ob nur die Argumente 5, 6, 2, 3 über apply im oberen Beispiel übergeben werden, statt dem ganzen Array.

Wenn das Array in einigen Fällen so groß wird, dass es zehntausend Element erreicht, sollte eine hybride Strategie genutzt werden: Man teilt das Array auf und übergibt diese Teile der Funktion:

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]);

Spezifikationen

Spezifikation Status Kommentar
ECMAScript 3rd Edition (ECMA-262) Standard Initiale Definition. Implementiert in JavaScript 1.3.
ECMAScript 5.1 (ECMA-262)
Die Definition von 'Function.prototype.apply' in dieser Spezifikation.
Standard  
ECMAScript 2015 (6th Edition, ECMA-262)
Die Definition von 'Function.prototype.apply' in dieser Spezifikation.
Standard  
ECMAScript Latest Draft (ECMA-262)
Die Definition von 'Function.prototype.apply' in dieser Spezifikation.
Entwurf  

Browserkompatibilität

FeatureChromeEdgeFirefoxInternet ExplorerOperaSafari
Grundlegende Unterstützung Ja Ja1 Ja Ja Ja
ES 5.1: generic array-like object as arguments Ja ?4 ? ? ?
FeatureAndroid webviewChrome for AndroidEdge mobileFirefox for AndroidOpera AndroidiOS SafariSamsung Internet
Grundlegende Unterstützung Ja Ja Ja4 Ja Ja Ja
ES 5.1: generic array-like object as arguments ? Ja ?4 ? ? Ja

Siehe auch

Schlagwörter des Dokuments und Mitwirkende

Schlagwörter: 
 Mitwirkende an dieser Seite: schlagi123, fscholz
 Zuletzt aktualisiert von: schlagi123,