Wie übergebe ich Variablen als Referenz in JavaScript? Ich habe 3 Variablen, für die ich mehrere Operationen ausführen möchte, also möchte ich sie in eine for-Schleife einfügen und die Operationen für jede ausführen.
Pseudocode:
myArray = new Array(var1, var2, var3);
for (var x = 0; x < myArray.length; x++){
//do stuff to the array
makePretty(myArray[x]);
}
//now do stuff to the updated vars
Was ist der beste Weg, dies zu tun?
javascript
variables
pass-by-reference
BFTrick
quelle
quelle
makePretty(var1); makePretty(var2); makePretty(var3); ...
arr = [var1, var2, var3]; for (var i = 0, len = arr.length; i < len; i++) { arr[i] = makePretty(arr[i]); }
- Sie müssen nur den vonmakePretty
back zurückgegebenen Wert in dem Slot im Array speichern .Antworten:
In JavaScript ist keine "Referenzübergabe" verfügbar. Sie können ein Objekt übergeben (dh Sie können einen Verweis auf ein Objekt als Wert übergeben) und dann eine Funktion den Objektinhalt ändern lassen:
Sie können die Eigenschaften eines Arrays mit einem numerischen Index durchlaufen und bei Bedarf jede Zelle des Arrays ändern.
Es ist wichtig zu beachten, dass "Pass-by-Reference" ein sehr spezifischer Begriff ist. Es bedeutet nicht einfach, dass es möglich ist, einen Verweis auf ein modifizierbares Objekt zu übergeben. Stattdessen bedeutet dies, dass es möglich ist, eine einfache Variable so zu übergeben, dass eine Funktion diesen Wert im aufrufenden Kontext ändern kann . So:
In einer Sprache wie C ++, ist es möglich , das zu tun , weil die Sprache tut (Art-of) hat Pass-by-reference.
edit - dies hat kürzlich (März 2015) Reddit erneut über einen Blog-Beitrag in die Luft gesprengt, der meinem unten erwähnten ähnelt, allerdings in diesem Fall über Java. Beim Lesen des Hin und Her in den Reddit-Kommentaren fiel mir ein, dass ein großer Teil der Verwirrung auf die unglückliche Kollision mit dem Wort "Referenz" zurückzuführen ist. Die Terminologie "Referenzübergabe" und "Wertübergabe" geht dem Konzept voraus, "Objekte" zu haben, mit denen in Programmiersprachen gearbeitet werden kann. Es geht wirklich überhaupt nicht um Objekte; Es geht um Funktionsparameter und insbesondere darum, wie Funktionsparameter mit der aufrufenden Umgebung "verbunden" sind (oder nicht). Bestimmtes,und es würde ziemlich genau so aussehen wie in JavaScript. Man könnte jedoch auch die Objektreferenz in der aufrufenden Umgebung ändern, und das ist der Schlüssel, den Sie in JavaScript nicht tun können. Eine Pass-by-Reference-Sprache würde nicht die Referenz selbst übergeben, sondern eine Referenz auf die Referenz .
bearbeiten - hier ist ein Blog-Beitrag zum Thema. (Beachten Sie den Kommentar zu diesem Beitrag, der erklärt, dass C ++ nicht wirklich über eine Referenz verfügt. Das stimmt. C ++ bietet jedoch die Möglichkeit, Verweise auf einfache Variablen zu erstellen, entweder explizit am Funktionspunkt Aufruf zum Erstellen eines Zeigers oder implizit beim Aufrufen von Funktionen, deren Argumenttypsignatur dies erfordert. Dies sind die wichtigsten Dinge, die JavaScript nicht unterstützt.)
quelle
Arrays und Objekte werden basierend auf diesen Bedingungen als Referenz oder als Wert übergeben:
Wenn Sie den Wert eines Objekts oder Arrays festlegen, ist dies Pass by Value.
object1 = {prop: "car"}; array1 = [1,2,3];
Wenn Sie einen Eigenschaftswert eines Objekts oder Arrays ändern, handelt es sich um Pass by Reference.
object1.prop = "car"; array1[0] = 9;
Code
quelle
Problemumgehung zum Übergeben von Variablen wie durch Referenz:
BEARBEITEN
Ja, eigentlich können Sie es ohne globalen Zugriff tun
quelle
Einfaches Objekt
Benutzerdefiniertes Objekt
Objekt
rvar
Variable Aussage
Oder:
Testcode
Ergebnis der Testkonsole
quelle
Ein weiterer Ansatz, um (lokale, primitive) Variablen als Referenz zu übergeben, besteht darin, die Variable mit dem Abschluss "on the fly" zu verpacken
eval
. Dies funktioniert auch mit "use strict". (Hinweis: Beachten Sie, dass dieseval
nicht für JS-Optimierer geeignet ist. Auch fehlende Anführungszeichen um den Variablennamen können zu unvorhersehbaren Ergebnissen führen.)Live-Beispiel https://jsfiddle.net/t3k4403w/
quelle
Es gibt eigentlich eine hübsche Lösung:
quelle
Ich habe mit der Syntax herumgespielt, um so etwas zu tun, aber es erfordert einige Helfer, die etwas ungewöhnlich sind. Es beginnt damit, dass 'var' überhaupt nicht verwendet wird, sondern ein einfacher 'DECLARE'-Helfer, der eine lokale Variable erstellt und über einen anonymen Rückruf einen Bereich dafür definiert. Indem wir steuern, wie Variablen deklariert werden, können wir sie in Objekte einschließen, sodass sie im Wesentlichen immer als Referenz übergeben werden können. Dies ähnelt einer der obigen Antworten von Eduardo Cuomo, für die folgende Lösung müssen jedoch keine Zeichenfolgen als Variablenbezeichner verwendet werden. Hier ist ein minimaler Code, um das Konzept zu zeigen.
quelle
eigentlich ist es wirklich einfach,
Das Problem besteht darin, zu verstehen, dass Sie nach dem Übergeben klassischer Argumente in eine andere schreibgeschützte Zone versetzt werden.
Die Lösung besteht darin, die Argumente mit dem objektorientierten Design von JavaScript zu übergeben.
Es ist dasselbe wie das Einfügen der Argumente in eine globale Variable / Gültigkeitsbereichsvariable, aber besser ...
Sie können auch versprechen Sachen die bekannte Kette zu genießen bis: hier ist das Ganze, mit Versprechen artigen Struktur
oder noch besser..
action.setArg(["empty-array"],"some string",0x100,"last argument").call()
quelle
this.arg
funktioniert nur mitaction
Instanz. Das funktioniert nicht.Ich persönlich mag die "Pass by Reference" -Funktionalität, die von verschiedenen Programmiersprachen angeboten wird, nicht. Vielleicht liegt das daran, dass ich gerade die Konzepte der funktionalen Programmierung entdecke, aber ich bekomme immer Gänsehaut, wenn ich Funktionen sehe, die Nebenwirkungen verursachen (wie das Manipulieren von Parametern, die als Referenz übergeben werden). Ich persönlich begrüße nachdrücklich das Prinzip der "Einzelverantwortung".
IMHO sollte eine Funktion nur ein Ergebnis / einen Wert mit dem Schlüsselwort return zurückgeben. Anstatt einen Parameter / ein Argument zu ändern, würde ich einfach den geänderten Parameter / Argument-Wert zurückgeben und alle gewünschten Neuzuweisungen dem aufrufenden Code überlassen.
Aber manchmal (hoffentlich sehr selten) ist es notwendig, zwei oder mehr Ergebniswerte von derselben Funktion zurückzugeben. In diesem Fall würde ich mich dafür entscheiden, alle resultierenden Werte in eine einzelne Struktur oder ein einzelnes Objekt aufzunehmen. Auch hier sollte die Verarbeitung von Neuzuweisungen dem aufrufenden Code entsprechen.
Beispiel:
Angenommen, die Übergabe von Parametern wird durch die Verwendung eines speziellen Schlüsselworts wie 'ref' in der Argumentliste unterstützt. Mein Code könnte ungefähr so aussehen:
Stattdessen würde ich eigentlich lieber so etwas machen:
Wenn ich eine Funktion schreiben müsste, die mehrere Werte zurückgibt, würde ich auch keine Parameter verwenden, die als Referenz übergeben werden. Also würde ich Code wie diesen vermeiden:
Stattdessen würde ich es vorziehen, beide neuen Werte innerhalb eines Objekts wie folgt zurückzugeben:
Diese Codebeispiele sind ziemlich vereinfacht, aber sie zeigen grob, wie ich persönlich mit solchen Dingen umgehen würde. Es hilft mir, verschiedene Verantwortlichkeiten am richtigen Ort zu halten.
Viel Spaß beim Codieren. :) :)
quelle
findStuff
einfach das resultierende Array zurückzugeben. Sie müssen auch einefoundArray
Variable deklarieren , damit ich ihr das resultierende Array direkt zuweisen kann :var foundArray = findStuff(inArray); if (foundArray.length > 0) { /* process foundArray */ }
. Dies würde 1) den aufrufenden Code lesbarer / verständlicher machen und 2) die interne Funktionalität (und damit auch die Testbarkeit) derfindStuff
Methode erheblich vereinfachen , wodurch sie in verschiedenen (Wieder-) Anwendungsfällen / Szenarien tatsächlich viel flexibler wird.Javascript kann Array-Elemente innerhalb einer Funktion ändern (es wird als Referenz auf das Objekt / Array übergeben).
Hier ist ein weiteres Beispiel:
quelle
Da JS kein starker Typ ist, können Sie Probleme auf viele verschiedene Arten lösen, wie in diesem Schritt dargestellt.
Aus Sicht der Wartbarkeit müsste ich jedoch Bart Hofland zustimmen. Die Funktion sollte Argumente dazu bringen, etwas zu tun, und das Ergebnis zurückgeben. Einfach wiederverwendbar machen.
Wenn Sie der Meinung sind, dass Variablen als Referenz übergeben werden müssen, ist es möglicherweise besser, sie in Objekte einzubauen, IMHO.
quelle
Abgesehen von der Pass-by-Reference-Diskussion könnten diejenigen, die noch nach einer Lösung für die genannte Frage suchen, Folgendes verwenden:
quelle
Ich weiß genau was du meinst. Das Gleiche in Swift wird kein Problem sein. Unterm Strich wird
let
nicht verwendetvar
.Die Tatsache, dass Grundelemente als Wert übergeben werden, aber die Tatsache, dass der Wert
var i
zum Zeitpunkt der Iteration nicht in die anonyme Funktion kopiert wird, ist gelinde gesagt ziemlich überraschend.quelle