467 Stimmen

Wie kann ich das Objekt "arguments" in ein Array in JavaScript umwandeln?

El arguments Objekt in JavaScript ist eine seltsame Warze - es verhält sich in den meisten Situationen wie ein Array, aber es ist nicht eigentlich ein Array-Objekt. Da es sich um wirklich etwas ganz anderes verfügt es nicht über die nützlichen Funktionen von Array.prototype wie forEach , sort , filter und map .

Es ist trivial einfach, ein neues Array aus einem Argument-Objekt mit einer einfachen for-Schleife zu konstruieren. Zum Beispiel sortiert diese Funktion ihre Argumente:

function sortArgs() {
    var args = [];
    for (var i = 0; i < arguments.length; i++)
        args[i] = arguments[i];
    return args.sort();
}

Allerdings ist dies eine ziemlich erbärmliche Sache zu tun, nur um Zugang zu den äußerst nützlichen JavaScript-Array-Funktionen zu bekommen. Gibt es einen eingebauten Weg, um es mit der Standardbibliothek zu tun?

1 Stimmen

0 Stimmen

Es gefällt mir nicht, dass alle Antworten auf diese Frage die Absicht erkennen lassen, eine Sortierung vorzunehmen, und sort hat alle Antworten durchdrungen, aber das Sortieren war nur ein Beispiel von etwas, das Sie könnte tun mit einer geeigneten Anordnung. Die Absicht war, das Array zu erhalten. Ich kann die Frage nicht einmal tadeln, weil es richtig "zum Beispiel" heißt. Dennoch hat jede Antwort beschlossen, "sortieren" in das Beispiel für die Umwandlung der Argumente in ein Array einzubauen - manchmal zu eng, indem man das Sortieren mit dem Erhalten eines Arrays von Argumenten verwechselt.

772voto

Jonathan Fingland Punkte 54655

ES6 mit Rest-Parametern

Wenn Sie in der Lage sind, ES6 zu verwenden, können Sie dies tun:

Rest Parameter

function sortArgs(...args) {
  return args.sort(function (a, b) { return a - b; });
}

document.body.innerHTML = sortArgs(12, 4, 6, 8).toString();

Wie Sie in der Link

Die Restparameter-Syntax ermöglicht es uns, eine unbestimmte Anzahl von Argumenten als Array darzustellen.

Wenn Sie neugierig sind auf die ... Syntax, heißt es Spread Operator und Sie können mehr lesen aquí .

ES6 mit Array.from()

Verwendung von Array.von :

function sortArgs() {
  return Array.from(arguments).sort(function (a, b) { return a - b; });
}

document.body.innerHTML = sortArgs(12, 4, 6, 8).toString();

Array.from konvertieren einfach Array-ähnliche oder Iterable-Objekte in Array-Instanzen.



ES5

Sie können auch einfach Array 's slice Funktion auf ein Argument-Objekt anwenden und es in ein Standard-JavaScript-Array umwandeln. Sie müssen es dann nur noch manuell über den Prototyp von Array referenzieren:

function sortArgs() {
    var args = Array.prototype.slice.call(arguments);
    return args.sort();
}

Warum funktioniert das? Nun, hier ist ein Auszug aus dem ECMAScript 5-Dokumentation selbst :

ANMERKUNG : Die slice Funktion ist absichtlich generisch; sie erfordert nicht, dass ihre este Wert ein Array-Objekt sein. Daher kann er auf andere Arten von Objekten übertragen und als Methode verwendet werden. Ob der slice Funktion erfolgreich auf ein Host-Objekt angewendet werden kann, hängt von der Implementierung ab.

Deshalb, slice funktioniert bei allem, was einen length Eigenschaft, die arguments bequem tut.


Si Array.prototype.slice zu lang ist, können Sie es durch die Verwendung von Array-Literalen etwas abkürzen:

var args = [].slice.call(arguments);

Ich habe jedoch den Eindruck, dass die erste Version eindeutiger ist, und würde sie daher vorziehen. Der Missbrauch der Array-Literal-Notation fühlt sich hakelig an und sieht seltsam aus.

5 Stimmen

In neueren Firefox-Versionen (2.0?) und ECMAScript 5 gibt es eine Array.slice-Methode, die dies ein wenig einfacher macht. Sie können sie wie folgt aufrufen: var arge = Array.slice(arguments, 0);.

2 Stimmen

Konvertierung von Array-ähnlichen Objekten in Arrays über slice() funktioniert leider nicht zuverlässig in allen Browsern - z.B. kann der IE Knotenlisten nicht auf diese Weise konvertieren; für eine allgemeine Funktion, die mit allen Array-ähnlichen Objekten funktioniert, führt kein Weg daran vorbei, manuell eine Schleife über die Einträge zu machen

9 Stimmen

Was ist das 0 für? Da es keine Argumente gibt, die Sie übergeben wollen, warum können Sie nicht einfach var args = Array.prototype.slice.call(arguments); ? [ Die MDC-Argumentseite ]( developer.mozilla.org/de/JavaScript/Referenz/ ) schlägt die Methode ohne den 0 .

40voto

jbmusso Punkte 3346

Es lohnt sich auch, auf folgende Punkte hinzuweisen diese Bluebird verspricht Bibliothek Wiki-Seite die zeigt, wie man die arguments Objekt in ein Array umwandeln, so dass die Funktion optimiert werden kann unter V8-JavaScript-Engine :

function doesntLeakArguments() {
    var args = new Array(arguments.length);
    for(var i = 0; i < args.length; ++i) {
        args[i] = arguments[i];
    }
    return args;
}

Diese Methode wird verwendet zugunsten von var args = [].slice.call(arguments); . Der Autor zeigt auch, wie ein Build-Schritt dazu beitragen kann, die Ausführlichkeit zu reduzieren.

2 Stimmen

+1 und danke für den Link zur Bluebird Optimization Killer Seite. PS: Ich habe kürzlich gesehen, dass diese Optimierung in der node-thunkify Projekt.

0 Stimmen

Für alle, die im Jahr 2021 lesen, auf der verlinkten Seite: "Bitte fassen Sie nichts von dem, was hier geschrieben steht, als Leistungsempfehlung auf, dies ist aus historischen Gründen hier."

30voto

matyr Punkte 5744
function sortArgs(){ return [].slice.call(arguments).sort() }

// Returns the arguments object itself
function sortArgs(){ return [].sort.call(arguments) }

Einige Array-Methoden sind absichtlich so gestaltet, dass das Zielobjekt kein tatsächliches Array sein muss. Sie verlangen nur, dass das Zielobjekt eine Eigenschaft namens Länge und Indizes (die Null oder eine größere ganze Zahl sein müssen).

[].sort.call({0:1, 1:0, length:2}) // => ({0:0, 1:1, length:2})

12voto

Verwendung:

function sortArguments() {
  return arguments.length === 1 ? [arguments[0]] :
                 Array.apply(null, arguments).sort();
}

Array(arg1, arg2, ...) gibt zurück. [arg1, arg2, ...]

Array(str1) gibt zurück. [str1]

Array(num1) gibt ein Array zurück, das die num1 Elemente

Sie müssen die Anzahl der Argumente überprüfen!

Array.slice Version (langsamer):

function sortArguments() {
  return Array.prototype.slice.call(arguments).sort();
}

Array.push Version (langsamer, schneller als Slice):

function sortArguments() {
  var args = [];
  Array.prototype.push.apply(args, arguments);
  return args.sort();
}

Move-Version (langsamer, aber kleine Größe ist schneller):

function sortArguments() {
  var args = [];
  for (var i = 0; i < arguments.length; ++i)
    args[i] = arguments[i];
  return args.sort();
}

Array.concat Version (die langsamste):

function sortArguments() {
  return Array.prototype.concat.apply([], arguments).sort();
}

1 Stimmen

Beachten Sie, dass aufgrund des Flattening-Verhaltens in Array.concat Array-Argumente akzeptiert werden. sortArguments(2,[3,0],1) liefert 0,1,2,3.

9voto

brad Punkte 70548

Wenn Sie jQuery verwenden, ist das Folgende meiner Meinung nach viel einfacher zu merken:

function sortArgs(){
  return $.makeArray(arguments).sort();
}

1 Stimmen

Das ist im Wesentlichen, was ich in reinem JS suchte, aber +1 für das solide Beispiel dafür, wie jQuery JS ein bisschen leichter zu verstehen macht.

2 Stimmen

"Wenn nicht noch ein Tag für ein Framework/eine Bibliothek enthalten ist, wird eine reine JavaScript-Antwort erwartet."

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X