• Jetzt anmelden. Es dauert nur 2 Minuten und ist kostenlos!

Array.prototype.slice.apply()

Status
Für weitere Antworten geschlossen.

zorkez

Neues Mitglied
Hallo,

bin gerade dabei mein JS etwas aufzubessern. Ich durchforste dabei verschiedene Frameworks und stoße z.B. auf Array.prototype.slice.apply().

Also soweit ich weiss, ist prototype dazu da, Methoden und Eigenschaften einer Klasse zu erweitern. Das geht ja i.d.R. durch eine Zuweisung. Diese fehlt hier aber.
Was slice und apply als einzelne Funktionen machen weiss ich auch.

Kann mir mal jemand erklären was diese Anweisung im Gesamten genau macht?

Ich lese das z.B. in Verbindung mit Organisation von JavaScripten

oder im prototype-FW ist das $A()

Danke im Voraus

Mit freundlichen Grüßen
 
Erstmal zu apply: https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Global_Objects/Function/apply

Code:
Array.prototype.slice.apply(iterable);
Ist ein Trick, um sich das umständliche Umwandeln des arguments-Objekts (oder hier den Inhalts der Variable iterable) in ein Array. Nur weil man über arguments u.Ä. iterieren kann heißt es noch nicht, dass es sich dabei um ein Array handelt.

Dazu wird eine beliebige Array-Objekt-Methode (hier slice) aufgerufen und der Kontext (this) auf das arguments-Objekt umgebogen.

Hat in JavaScript eine Funktion einen Prototypen, wird diese zum Objekt (im Sinne von OOP). Prototypen werden über Instanzen hinweg geteilt. So kann ich einem Objekten Funktionen hinzufügen, welche dann auch in bereits instanzierten Objekten verfügbar werden.

Prototypen kann ich so auch für die Vererbung nutzen:
Code:
function Foo() {}
Foo.prototype = {};

function Bar() {}
Bar.prototype = Foo.prototype;
Bar.prototype.constructor = Bar; // Constructor neu definieren
 
Danke für die Antwort.
Ok, hab mich damit nochmal auseinander gesetzt.

Der Aufruf erfolgt ja per Array.prototype. Warum denn nicht mit Array.slice.apply(iterable)? Funktioniert doch genauso.
Ich verstehe nicht, warum hier prototype verwendet werden soll.
Generell entzieht sich mir die Logik dieser Syntax sowieso, da slice doch zum Auswählen von Array-Elementen gedacht ist.

Normalerweise verwende ich prototype, um eine Methode/Eigenschaft hinzuzufügen (wie crash ja geschrieben hat).

Code:
Array.prototype.pop = function() {}

Das findet hier ja als Zuweisung statt und mit Array.prototype.slice.apply(iterable) sieht mir das wie ein Aufruf aus....

Also ich hab mal nach den Befehlen gegoogelt und finde nix gescheites dazu.

Wahrscheinlich steh ich gerade aufm Schauch?!

@Crash:

So wie Sie hier das schreiben, hab ich das ja auch verstanden, erklärt meiner Meinung nach aber nicht die obige Syntax.

Dazu wird eine beliebige Array-Objekt-Methode (hier slice) aufgerufen
Das kann ich auch nicht glauben, wenn ich nämlich eine andere Objekt-Methode angebe kommt ein ganz anderes Ergebnis raus.

Die interne Funktionsweise erschließt sich mir hier nicht ganz.

Danke für Antworten

Mit freundlichen Grüßen
 
[].slice.apply(), Array.slice.apply() und (new Array).slice.apply() hätten genauso funktioniert.

Ich hab auch eine Weile [].slice.apply benutzt, aber es stellt sich heraus, dass diese Methode langsamer ist, da hier vorher eine Array-Objekt-Instanz erzeugt wird. Array.slice.apply() dürfe an sich gleich schnell sein, wie Array.prototype.slice.apply().

Mal ein nach dem anderen:
Erstmal hast du das Array-Objekt, dann dessen Prototype (an dieser Eigenschaft hängen alle Methoden/Eigenschaften eines Objekts), dann eine Methode des Array-Objekts (slice), welche mit apply() aufgerufen wird, wobei der erste Parameter den Kontext angibt.

Bei deinem Beispiel wird dort das arguments-Objekt reingestopft. Nun wird die Methode slice des Array-Objekts auf das arguments-Objekt angewendet.

Theoretisch hätte es auch eine andere Methode sein können.

Das Ergebnis ist, dass man statt eines Arguments-Objekts ein echtes Array ist, denn arguments ist kein Array! Genau wie getElementsByTagName() kein Array zurückliefert! Das ist wesentlich in DOM/JavaScript.

Anderes Beispiel:
<crash> >> Array.prototype.slice.apply("test");
<E_NOTICE> t,e,s,t
Macht aus einem String ein Array, da Strings intern nur Buchstaben-"Arrays" sind. Man hätte auch "test".split("") schreiben können, aber es ist nur ein Beispiel.
 
Super, danke für die Antwort. Ich meine ich bekomme ja meine Skripte zum laufen. Es ärgert mich halt nur, wenn ich nicht genau weiss wie das funktioniert.

Auch nach der Antwort erschließt sich mir nicht, warum man prototype verwenden sollte. Ich hatte auch mal die Vermutung das es vielleicht eine Performance-Frage ist. Deshalb werde ich das einfach mal so übernehmen.
Ich werde schon noch auf die Antwort stoßen...

Nochmals danke für die Antwort. Super Seite hier.
Werde vielleicht noch öfter solche Fragen stellen ;-)

Mit freundlichen Grüßen
 
Steht doch da:
Ich hab auch eine Weile [].slice.apply benutzt, aber es stellt sich heraus, dass diese Methode langsamer ist, da hier vorher eine Array-Objekt-Instanz erzeugt wird. Array.slice.apply() dürfe an sich gleich schnell sein, wie Array.prototype.slice.apply().
Aus Performencegründen
 
Status
Für weitere Antworten geschlossen.
Zurück
Oben