Website-Suche

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


Das arguments-Objekt in JavaScript ist eine merkwürdige Eigenheit - es verhält sich in den meisten Situationen wie ein Array, ist aber tatsächlich kein Array-Objekt. Da es wirklich etwas ganz anderes ist, verfügt es nicht über die nützlichen Funktionen von Array.prototype wie forEach, sort, filter und map.

Es ist denkbar einfach, ein neues Array aus einem Arguments-Objekt mit einer einfachen for-Schleife zu erstellen. 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();
}

Es ist jedoch eine ziemlich erbärmliche Sache, dies einfach tun zu müssen, nur um Zugriff auf die äußerst nützlichen JavaScript-Array-Funktionen zu erhalten. Gibt es eine eingebaute Möglichkeit, dies mit der Standardbibliothek zu tun?

Antwort #1

ES6 mit Rest-Parametern

Wenn Sie ES6 verwenden können, können Sie Folgendes verwenden:

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 im Link lesen können

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

Wenn Sie neugierig auf die ...-Syntax sind, wird sie Spread-Operator genannt und Sie können hier mehr darüber lesen.

ES6 unter Verwendung von Array.from()

Verwendung von Array.from:

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

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

Array.from konvertiert einfach Array-ähnliche oder durchlaufbare Objekte in Array-Instanzen.

ES5

Sie können tatsächlich einfach die slice-Funktion von Array auf einem Arguments-Objekt verwenden, und es wird in ein standardmäßiges JavaScript-Array konvertiert. Sie müssen nur manuell über das Prototype von Array darauf zugreifen:

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

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

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

Daher funktioniert slice auf allem, was eine length-Eigenschaft hat, was arguments zum Glück tut.

Wenn Array.prototype.slice für Sie zu umständlich ist, können Sie es leicht abkürzen, indem Sie Array-Literale verwenden:

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

Ich habe jedoch das Gefühl, dass die frühere Version expliziter ist, daher würde ich diese lieber verwenden. Die Verwendung der Array-Literal-Notation wirkt hackig und sieht seltsam aus.

Antwort #2

Es lohnt sich auch, auf diese Wiki-Seite der Bluebird-Promises-Bibliothek zu verweisen, die zeigt, wie man das arguments-Objekt in ein Array umwandelt, auf eine Weise, die die Funktion unter der V8-JavaScript-Engine optimierbar macht:

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 zugunsten von var args=[].slice.call(arguments); verwendet. Der Autor zeigt auch, wie ein Build-Schritt helfen kann, die Redundanz zu verringern.

Antwort #3

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 erfordern nur, dass das Ziel eine Eigenschaft namens length und Indizes hat (die null oder größere Ganzzahlen sein müssen).

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

Antwort #4

Verwenden :

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

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

Array(str1) gibt [str1] zurück

Array(num1) gibt ein Array zurück, das num1 Elemente enthält

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

Verschiebe 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();
}

Version von Array.concat (am langsamsten):

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

Verwandte Artikel