Wie bekomme ich ein Stück aus "Argumenten"?


80

Alles, was Sie wissen, argumentsist ein spezielles Objekt, das alle an die Funktion übergebenen Argumente enthält.

Und solange es sich nicht um ein Array handelt, können Sie so etwas nicht verwenden arguments.slice(1).

Also die Frage - wie schneidet man alles außer dem ersten Element ab arguments?

UPD :

Es scheint, als gäbe es keinen Weg, ohne es in ein Array mit zu konvertieren

var args = Array.prototype.slice.call(arguments);

Wenn jemand eine andere Lösung veröffentlicht, wäre es großartig, wenn nicht - ich werde die erste mit der obigen Zeile als Antwort überprüfen.


+ zerkms es gibt in der Tat einen besseren Weg als es zu nehmen argumentsund in ein Array usw. umzuwandeln. Bitte siehe meine Antwort unten.
Umur Karagöz

Antworten:


20

Das Einmischen in Array-Funktionen ist eigentlich nicht notwendig.

Die Verwendung der Restparametersyntax ...rest ist sauberer und bequemer.

Beispiel

function argumentTest(first, ...rest) {
  console.log("First arg:" + first);

  // loop through the rest of the parameters
  for (let arg of rest) {
    console.log("- " + arg);
  }
}

// call your function with any number of arguments
argumentTest("first arg", "#2", "more arguments", "this is not an argument but a contradiction");

...Sich ausruhen


Ja, ich stimme zu, dass es heutzutage bequemer ist. Ich habe Sie positiv bewertet, aber ich werde die überprüfte 5 Jahre alte Antwort nicht nachträglich ändern.
Zerkms

2
Jetzt, nach einem weiteren Jahr, denke ich, ist es an der Zeit, auf die neuen ES-Standards
umzusteigen

dieses Gefühl, wenn Sie +15 Punkte für eine einjährige Antwort erhalten :-D
zerkms

133

Frage: Wie schneide ich alles außer dem ersten Element ab arguments?

Im Folgenden wird ein Array zurückgegeben, das alle Argumente außer dem ersten enthält:

var slicedArgs = Array.prototype.slice.call(arguments, 1);

Sie müssen nicht argumentszuerst in ein Array konvertieren , sondern alles in einem Schritt erledigen.


Ich glaube, das hat einen Nachteil. Wenn es nur ein zusätzliches Argument gibt (außer dem ersten), wird nichts zurückgegeben.
Trevor

@Trevor - Nein, es wird ein Array mit einem Element zurückgegeben, das das zweite Argument ist. (Warum sollte es nichts zurückgeben?)
nnnnnn

4
Die Empfehlung hier besagt, dass Sie Slice nicht für Argumente verwenden sollten, da dies die Optimierung der JavaScript-Engine verhindert.
Jonathan Lin

1
Eine ausführlichere Erklärung finden Sie hier
David Chase

4
@ David - Der „im Detail“ Link sagt noch nicht zu verwenden , .slice()auf arguments, aber der einzige Grund ist , da es JS - Engine Optimierung der Funktion verhindert. Es ist also nicht so, dass es fehlschlägt, es könnte nur langsamer sein. Ich werde keinen Code schreiben, um die Optimierung in der JS-Engine des Tages zu berücksichtigen, nicht, wenn die Engine von morgen das Optimierungsproblem gelöst haben könnte, und auf jeden Fall wird der Unterschied für den Benutzer wahrscheinlich in den meisten Fällen nicht wahrnehmbar sein Fälle. Es ist besser, zuerst klaren und einfach zu wartenden Code zu schreiben und dann nur dann zurückzukehren und zu optimieren, wenn ein messbares Leistungsproblem auftritt.
nnnnnn

11

Sie können "schneiden, ohne zu schneiden", indem Sie das Argumentobjekt prozedural durchlaufen:

function fun() {
  var args = [];

  for (var i = 1; i < arguments.length; i++) {
    args.push(arguments[i]);
  }

  return args;
}

fun(1, 2, 3, 4, 5); //=> [2, 3, 4, 5]

2
Ja, es macht die Arbeit aber macht keinen Sinn , für den Fall , wir haben ein .slice();-)
zerkms

Natürlich ist es einfacher zu bedienen Array.prototype.slice, aber Ihre Frage war, ob es einen anderen Weg gibt.
Paul Rosania

ja, danke dafür ;-) (obwohl ich offensichtlich weiß über for:-P)
zerkms

Haha, ich hoffe ich klang nicht banal. Manchmal sind es nützliche Informationen zu SO!
Paul Rosania

3
+1 Dies scheint die einzig richtige Lösung für V8 zu sein. Schauen Sie sich das Optimierungs-Benchmarking hier an: jsperf.com/leaky-args
Tom Auger

11

Von https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/arguments :

Sie sollten nicht auf Argumente verzichten, da dies Optimierungen in JavaScript-Engines (z. B. V8) verhindert. Versuchen Sie stattdessen, ein neues Array zu erstellen, indem Sie das Argumentobjekt durchlaufen.

Die obige Antwort von Paul Rosiana ist also richtig


4
Vielleicht so. Aber ich sehe nicht, wie Optimierungs-Engines den Einzeiler der akzeptierten Antwort nicht so behandeln und optimieren können, wie sie es wünschen. Auf lange Sicht ist es immer ein Ärgernis, wenn wir anfangen, für die Optimierer (des Tages) zu codieren - ich persönlich bevorzuge die Klarheit des Codes.
Akauppi

2
'Slice' ändert sich nicht. Es wird eine flache Kopie der Elemente aus dem ursprünglichen Array zurückgegeben. Elemente des ursprünglichen Arrays werden in das zurückgegebene Array kopiert. Daher kann ich nicht verstehen, was der Unterschied zwischen manuellem Kopieren in ein neues Array und Slice ist.
Maxim

Ab 2018 ist die Warnung nicht mehr da. Wir sollten in Sicherheit sein, denke ich.
GBF_Gabriel

9

Dies kann ein Weg sein:

var args = Array.from(arguments).slice(1);

In diesen Tagen ist es überhaupt nicht notwendig:function foo(...args)
Zerkms

@zerkms Ich wollte Ihren Vorschlag aus Leistungsgründen ablehnen, aber mein Test zeigt Ruheparameter als die schnellste Lösung! gist.github.com/18d590d12aef1e90d2ed262f4fab0c96
Cody Allan Taylor

@ CodAllanTaylor-Implementierungen verbessern sich. Wenn Sie keinen wirklich, wirklich, wirklich wichtigen Grund haben, dies nicht zu
tun

0

Sie können die Methode verwenden [].slice.call(arguments, 1)

[] .slice gibt Ihnen das Slice-Funktionsobjekt zurück und Sie können es als argumentsund 1die Parameter aufrufen


Haben Sie Änderungen vorgenommen, bevor Sie Ihre Antworten veröffentlicht haben? Die identische (und sogar etwas bessere, da sie kein Wegwerfarray zuweist) Antwort wurde bereits veröffentlicht und überprüft.
Zerkms

0

Sie können ... rest innerhalb der Funktion verwenden, um das erste und den Rest der Argumente zu trennen:

function foo(arr) {
  const [first, ...rest] = arguments;
  console.log(`first = ${first}`);
  console.log(`rest = ${rest}`);
}
//Then calling the function with 3 arguments:
foo(1,2,3)


Ja, die Zukunft ist endlich da :-D
zerkms
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.