Ich weiß, dass es verwendet wird, um Argumente zu einem echten Array zu machen, aber ich verstehe nicht, was bei der Verwendung passiert Array.prototype.slice.call(arguments)
474
Ich weiß, dass es verwendet wird, um Argumente zu einem echten Array zu machen, aber ich verstehe nicht, was bei der Verwendung passiert Array.prototype.slice.call(arguments)
Antworten:
Was unter der Haube passiert, ist, dass, wenn
.slice()
es normal aufgerufen wird,this
es sich um ein Array handelt, das dann nur über dieses Array iteriert und seine Arbeit erledigt.Wie ist
this
in der.slice()
Funktion ein Array? Denn wenn Sie dies tun:... das wird
object
automatisch zum Wert vonthis
in dermethod()
. Also mit:... das
[1,2,3]
Array wird als Wert vonthis
in gesetzt.slice()
.Aber was wäre, wenn Sie etwas anderes als
this
Wert ersetzen könnten ? Solange alles, was Sie ersetzen, eine numerische.length
Eigenschaft und eine Reihe von Eigenschaften hat, die numerische Indizes sind, sollte es funktionieren. Dieser Objekttyp wird häufig als Array-ähnliches Objekt bezeichnet .Mit den Methoden
.call()
und.apply()
können Sie den Wert von in einer Funktion manuell festlegenthis
. Wenn wir also den Wert vonthis
in.slice()
auf ein Array-ähnliches Objekt setzen ,.slice()
wird einfach angenommen, dass es mit einem Array funktioniert, und es wird seine Sache tun.Nehmen Sie dieses einfache Objekt als Beispiel.
Dies ist offensichtlich kein Array, aber wenn Sie es als
this
Wert festlegen können,.slice()
funktioniert es einfach, da es wie ein Array aussieht.slice()
, um ordnungsgemäß zu funktionieren.Beispiel: http://jsfiddle.net/wSvkv/
Wie Sie in der Konsole sehen können, erwarten wir folgendes Ergebnis:
Dies passiert also, wenn Sie ein
arguments
Objekt alsthis
Wert von festlegen.slice()
. Daarguments
es eine.length
Eigenschaft und eine Reihe von numerischen Indizes hat,.slice()
geht es einfach so, als würde es an einem echten Array arbeiten.quelle
Array.prototype.slice
Methodenbeschreibung.for-in
Aussage, die keine Ordnung garantiert. Der von.slice()
definierte Algorithmus definiert eine numerische Reihenfolge, die0
mit dem.length
des angegebenen Objekts (oder Arrays oder was auch immer) beginnt und damit endet (nicht inklusive ). Somit ist die Reihenfolge für alle Implementierungen garantiert konsistent.var obj = {2:"two", 0:"zero", 1: "one"}
. Wenn wirfor-in
das Objekt aufzählen, gibt es keine Garantie für die Bestellung. Wenn wir jedoch verwendenfor
, können wir die Reihenfolge manuell erzwingen :for (var i = 0; i < 3; i++) { console.log(obj[i]); }
. Jetzt wissen wir, dass die Eigenschaften des Objekts in aufsteigender numerischer Reihenfolge erreicht werden, die wir durch unserefor
Schleife definiert haben . Das.slice()
macht es. Es ist egal, ob es ein tatsächliches Array hat. Es beginnt nur bei0
und greift in einer aufsteigenden Schleife auf Eigenschaften zu.Das
arguments
Objekt ist eigentlich keine Instanz eines Arrays und verfügt über keine der Array-Methoden. Funktioniert alsoarguments.slice(...)
nicht, da das Argumentobjekt nicht über die Slice-Methode verfügt.Arrays haben diese Methode, und da das
arguments
Objekt einem Array sehr ähnlich ist, sind beide kompatibel. Dies bedeutet, dass wir Array-Methoden mit dem Argument-Objekt verwenden können. Und da Array-Methoden mit Blick auf Arrays erstellt wurden, geben sie eher Arrays als andere Argumentobjekte zurück.Warum also verwenden
Array.prototype
? DasArray
ist das Objekt, aus dem wir neue Arrays erstellen (new Array()
), und diese neuen Arrays sind übergebene Methoden und Eigenschaften wie Slice. Diese Methoden werden im[Class].prototype
Objekt gespeichert . Aus Effizienzgründen erhalten wir die Slice-Methode nicht direkt von(new Array()).slice.call()
oder[].slice.call()
, sondern direkt vom Prototyp. Auf diese Weise müssen wir kein neues Array initialisieren.Aber warum müssen wir das überhaupt tun? Nun, wie Sie sagten, konvertiert es ein Argumentobjekt in eine Array-Instanz. Der Grund, warum wir Slice verwenden, ist jedoch eher ein "Hack" als alles andere. Die Slice-Methode nimmt ein Slice eines Arrays und gibt dieses Slice als neues Array zurück. Wenn keine Argumente an das Objekt übergeben werden (außer dem Argumentobjekt als Kontext), nimmt die Slice-Methode einen vollständigen Teil des übergebenen "Arrays" (in diesem Fall des Argumentobjekts) und gibt es als neues Array zurück.
quelle
Normalerweise anrufen
kopiert das Array
a
inb
. Das können wir jedoch nichtweil
arguments
es kein echtes Array ist und keineslice
Methode hat.Array.prototype.slice
ist dieslice
Funktion für Arrays undcall
führt die Funktion mitthis
set to ausarguments
.quelle
prototype
? ist keineslice
nativeArray
Methode?Array
eine Konstruktorfunktion ist und die entsprechende "Klasse" istArray.prototype
. Sie können auch verwenden[].slice
slice
ist eine Methode für jedeArray
Instanz, jedoch nicht dieArray
Konstruktorfunktion. Sie verwenden,prototype
um auf Methoden der theoretischen Instanzen eines Konstruktors zuzugreifen.Zunächst sollten Sie lesen, wie der Funktionsaufruf in JavaScript funktioniert . Ich vermute, dass allein genug ist, um Ihre Frage zu beantworten. Aber hier ist eine Zusammenfassung dessen, was passiert:
Array.prototype.slice
extrahiert die Methode aus dem Prototyp . Ein direkter Aufruf funktioniert jedoch nicht, da es sich um eine Methode (keine Funktion) handelt und daher einen Kontext (ein aufrufendes Objekt ) erfordert , da es sonst ausgelöst wird .slice
Array
this
Uncaught TypeError: Array.prototype.slice called on null or undefined
Mit dieser
call()
Methode können Sie den Kontext einer Methode angeben, sodass diese beiden Aufrufe im Wesentlichen gleichwertig sind:Mit der Ausnahme, dass Ersteres erfordert, dass die
slice
Methode insomeObject
der Prototypenkette vorhanden ist (wie dies auch der Fall istArray
), während Letzteres diesomeObject
manuelle Übergabe des Kontextes ( ) an die Methode ermöglicht.Letzteres ist auch die Abkürzung für:
Welches ist das gleiche wie:
quelle
quelle
Array.prototype.slice.call (Argumente) ist die altmodische Methode, um Argumente in ein Array zu konvertieren.
In ECMAScript 2015 können Sie Array.from oder den Spread-Operator verwenden:
quelle
Es liegt daran, wie MDN feststellt
Hier rufen wir
slice
das native Objekt aufArray
und nicht dessen Implementierung und deshalb das Extra.prototype
quelle
Vergessen Sie nicht, dass eine grundlegende Grundlage dieses Verhaltens das Typ-Casting ist, das vollständig in die JS-Engine integriert ist.
Slice nimmt nur ein Objekt (dank der vorhandenen Eigenschaft arguments.length) und gibt ein Array-Objekt zurück, das nach Ausführung aller Operationen umgewandelt wurde.
Dieselbe Logik, die Sie testen können, wenn Sie versuchen, die String-Methode mit einem INT-Wert zu behandeln:
Und das erklärt die obige Aussage.
quelle
Es verwendet die
slice
Methode, die Arrays haben, und ruft sie mitthis
demarguments
Objekt auf. Dies bedeutet, dass es so heißt, als hätten Siearguments.slice()
angenommenarguments
eine solche Methode gibt.Wenn Sie ein Slice ohne Argumente erstellen, werden einfach alle Elemente übernommen, sodass die Elemente einfach
arguments
in ein Array kopiert werden .quelle
Nehmen wir an, Sie haben:
function.apply(thisArg, argArray )
Die Slice () -Methode wählt einen Teil eines Arrays aus und gibt das neue Array zurück.
Wenn Sie also
Array.prototype.slice.apply(arguments, [0])
das Array aufrufen, wird die Slice-Methode für Argumente aufgerufen (bind).quelle
Vielleicht etwas spät, aber die Antwort auf all dieses Durcheinander ist, dass call () in JS für die Vererbung verwendet wird. Wenn wir dies zum Beispiel mit Python oder PHP vergleichen, wird call jeweils als super () verwendet. init () oder parent :: _ construct ().
Dies ist ein Beispiel für seine Verwendung, das alles verdeutlicht:
Referenz: https://developer.mozilla.org/en-US/docs/Learn/JavaScript/Objects/Inheritance
quelle
Wenn .slice () normal aufgerufen wird, handelt es sich um ein Array. Anschließend wird das Array einfach durchlaufen und seine Arbeit erledigt.
quelle
Ich schreibe das nur, um mich daran zu erinnern ...
Oder verwenden Sie einfach diese praktische Funktion $ A , um die meisten Dinge in ein Array zu verwandeln.
Beispiel Verwendung ...
quelle