Übergeben eines Arrays als Funktionsparameter in JavaScript

290

Ich möchte eine Funktion mit einem Array als Parameter aufrufen:

const x = ['p0', 'p1', 'p2'];
call_me(x[0], x[1], x[2]); // I don't like it

function call_me (param0, param1, param2 ) {
  // ...
}

Gibt es eine bessere Möglichkeit, den Inhalt von xin call_me()weiterzugeben?

Robert
quelle

Antworten:

421
const args = ['p0', 'p1', 'p2'];
call_me.apply(this, args);

Siehe MDN-Dokumente für Function.prototype.apply().


Wenn die Umgebung ECMAScript 6 unterstützt, können Sie stattdessen ein Spread-Argument verwenden:

call_me(...args);
KaptajnKold
quelle
9
Als Randnotiz: Wenn jemand stattdessen ein assoziatives Array (benannte Schlüssel) übergeben möchte, verwenden Sie ein Objekt. Als ich von PHP kam (und immer von Google zu diesem Thread geführt habe), habe ich eine Weile gebraucht, um das herauszufinden. Sie können dann das gesamte Objekt als Parameter übergeben. w3schools.com/js/js_objects.asp
timhc22
Vielen Dank, dass Sie auf das Argument "Verbreitung" hingewiesen haben! Wusste nichts davon.
Thomas An
@timhc - Ihr Kommentar zur Randnotiz ist faszinierend, aber ich kann ihn nicht analysieren (ich bin ein Javascript-Neuling, der einige Tutorials durcharbeitet). In JS, eine assoziative Array ist ein Objekt gemäß mehreren Anleitungen.
NateT
@ timhc22, und wenn Sie das json-Objekt verwenden, um es als Parameter an eine Funktion zu übergeben, vergessen Sie nicht die Parameterzerstörung für eine bessere Lesbarkeit
Muhammad Omer Aslam
113

Warum übergeben Sie nicht das gesamte Array und verarbeiten es nach Bedarf innerhalb der Funktion?

var x = [ 'p0', 'p1', 'p2' ]; 
call_me(x);

function call_me(params) {
  for (i=0; i<params.length; i++) {
    alert(params[i])
  }
}
Karl Johan
quelle
37
Es ist, weil ich call_me () nicht ändern kann. Es ist in einer anderen Bibliothek definiert und es ist nicht möglich, mit der API herumzuspielen.
Robert
62
+1, denn obwohl es die ursprüngliche Frage nicht beantwortet, ist es wahrscheinlich das, wonach die über 100.000 Personen, die diese Seite angesehen haben, gesucht haben.
Ishikawa
Kann jemand erklären, was die Zeile "call_me (x)" tut? Es scheint, als wäre es ein Funktionsname ohne das Funktionsschlüsselwort? Was genau macht es?
schwamm
1
@swam Es ist ein Aufruf der call_meFunktion. Am Ende fehlt nur ein Semikolon.
SantiBailors
@swam führt die deklarierte Funktion call_me (params) aus.
Julio Rodriguez
43

Angenommen, call_me ist eine globale Funktion, so erwarten Sie nicht, dass dies festgelegt wird.

var x = ['p0', 'p1', 'p2'];
call_me.apply(null, x);
Plexer
quelle
41

Im ES6-Standard gibt es einen neuen Spread-Operator, ... der genau das tut.

call_me(...x)

Es wird von allen gängigen Browsern außer IE unterstützt.

Der Spread-Operator kann viele andere nützliche Dinge tun, und die verknüpfte Dokumentation zeigt dies wirklich gut.

BoltKey
quelle
7

Da hatte @KaptajnKold geantwortet

var x = [ 'p0', 'p1', 'p2' ];
call_me.apply(this, x);

Außerdem müssen Sie nicht alle Parameter für die Funktion call_me definieren. Sie können einfach verwendenarguments

function call_me () {
    // arguments is a array consisting of params.
    // arguments[0] == 'p0',
    // arguments[1] == 'p1',
    // arguments[2] == 'p2'
}
徐 竟 峰
quelle
4
Dies ist eine so schlechte Praxis ... Sie werden nicht sehen können, was die Funktion benötigt, und jeder Parameter ist optional, wenn Sie sich die Funktion ansehen.
Robin
3

Beachten Sie dies

function FollowMouse() {
    for(var i=0; i< arguments.length; i++) {
        arguments[i].style.top = event.clientY+"px";
        arguments[i].style.left = event.clientX+"px";
    }

};

// ---------------------------

HTML-Seite

<body onmousemove="FollowMouse(d1,d2,d3)">

<p><div id="d1" style="position: absolute;">Follow1</div></p>
<div id="d2" style="position: absolute;"><p>Follow2</p></div>
<div id="d3" style="position: absolute;"><p>Follow3</p></div>


</body>

kann die Funktion mit beliebigen Args aufrufen

<body onmousemove="FollowMouse(d1,d2)">

oder

<body onmousemove="FollowMouse(d1)">
ali.by.
quelle
Dies ist eindeutig Teil der Antwort. "Argumente" wird definitiv benötigt, um das Array nach dem Aufruf zurückzubekommen. Vielen Dank!
FlorianB
2

Funktionsargumente können auch Arrays sein:

function foo([a,b,c], d){
  console.log(a,b,c,d);
}

foo([1,2,3], 4)

Natürlich kann man auch Spread verwenden :

function foo(a, b, c, d){
  console.log(a, b, c, d);
}

foo(...[1, 2, 3], 4)

vsync
quelle
2

Bei Verwendung des Spread-Operators müssen wir beachten, dass dies der letzte oder einzige übergebene Parameter sein muss. Sonst wird es scheitern.

function callMe(...arr){ //valid arguments
    alert(arr);
}

function callMe(name, ...arr){ //valid arguments
    alert(arr);
}

function callMe(...arr, name){ //invalid arguments
    alert(arr);
}

Wenn Sie ein Array als Startargument übergeben müssen, können Sie Folgendes tun:

function callMe(arr, name){
    let newArr = [...arr];
    alert(newArr);
}
Naba
quelle
1

Sie können den Spread-Operator in einer grundlegenderen Form verwenden

[].concat(...array)

im Fall von Funktionen, die Arrays zurückgeben, von denen jedoch erwartet wird, dass sie als Argumente übergeben werden

Beispiel:

function expectArguments(...args){
  return [].concat(...args);
}

JSON.stringify(expectArguments(1,2,3)) === JSON.stringify(expectArguments([1,2,3]))
rman
quelle
0

Die Antwort wurde bereits gegeben, aber ich möchte nur mein Stück Kuchen geben. Was Sie erreichen möchten, wird method borrowingim Kontext von JS aufgerufen, dh wenn wir eine Methode aus einem Objekt nehmen und sie im Kontext eines anderen Objekts aufrufen. Es ist durchaus üblich, Array-Methoden zu verwenden und sie auf Argumente anzuwenden. Lassen Sie mich Ihnen ein Beispiel geben.

Wir haben also eine "super" -Hashing-Funktion, die zwei Zahlen als Argument verwendet und eine "super sichere" Hash-Zeichenfolge zurückgibt:

function hash() {
  return arguments[0]+','+arguments[1];
}

hash(1,2); // "1,2" whoaa

So weit so gut, aber wir haben wenig Probleme mit dem obigen Ansatz, es ist eingeschränkt, funktioniert nur mit zwei Zahlen, das ist nicht dynamisch, lassen Sie es mit einer beliebigen Zahl funktionieren und außerdem müssen Sie kein Array übergeben (Sie können wenn Sie immer noch darauf bestehen). Ok, genug geredet, lass uns kämpfen!

Die natürliche Lösung wäre die Verwendung der folgenden arr.joinMethode:

function hash() {
  return arguments.join();
}

hash(1,2,4,..); //  Error: arguments.join is not a function

Oh Mann. Das wird leider nicht funktionieren. Da wir Hash (Argumente) und Argumente aufrufen, ist das Objekt sowohl iterierbar als auch Array-ähnlich, aber kein echtes Array. Wie wäre es mit dem folgenden Ansatz?

function hash() {
  return [].join.call(arguments);
}

hash(1,2,3,4); // "1,2,3,4" whoaa

Der Trick heißt method borrowing.

Wir leihen eine joinMethode aus einem regulären Array aus [].join.und verwenden sie [].join.call, um sie im Kontext von auszuführen arguments.

Warum funktioniert es?

Das liegt daran, dass der interne Algorithmus der nativen Methode arr.join(glue)sehr einfach ist.

Entnommen aus der Spezifikation fast "wie sie ist":

Let glue be the first argument or, if no arguments, then a comma ",".
Let result be an empty string.
Append this[0] to result.
Append glue and this[1].
Append glue and this[2].
Do so until this.length items are glued.
Return result.

Technisch gesehen nimmt es dies und verbindet dieses [0], dieses [1] ... usw. miteinander. Es ist absichtlich so geschrieben, dass es jedes Array-ähnliche zulässt (kein Zufall, viele Methoden folgen dieser Praxis). Deshalb funktioniert es auch mitthis=arguments.

Humoyun Ahmad
quelle