call-by-reference vs call-by-value
Bei der Übergabe einer Variablen an eine Funktion mit call-by-value wird die Variable kopiert und alle Änderungen durch die Funktion sind nichtig, wenn Funktion abgearbeitet ist.
In allen Programmiersprachen bedeutet call-by-reference, dass die Variable bei der Übergabe an eine Funktion nicht kopiert wird und alle Änderungen seitens der Funktion erhalten bleiben, wenn die Funktion abgearbeitet ist.
pass by value
Diese Mimic wird auch als pass by value bezeichnet, denn der Funktion wird nur der Wert der Variablen übergeben, nicht aber die Referenz auf die Speicherstelle.
function machWas( arg ) { arg = 17; } function caller() { let myVar = 2000; machWas (myVar); console.log ("myVar danach " + myVar); } caller();
myVar danach 2000
Nach dem Aufruf von machWas aus der Funktion caller ist myVar weiterhin unverändert 2000. Der Funktion machWas wurde im Grunde genommen nur eine Kopie von myVar übergeben.
call by reference
call by reference ist eine weitere Technik bei der Übernahme von Variablen in Funktionsargumenten. Bei call-by-reference kann die Funktion nicht nur die Variable für interne Berechnungen verwenden, sondern den Wert der Variablen auch verändern.
In JavaScript ist call by value bei Funktionsaufrufen mit Argumenten der Normalfall. In anderen Programmiersprachen gibt es Mechanismen, um Funktionsaufrufe als call by reference auch dann zu erzwingen, wenn das Argument kein Objekt ist. In PHP z.B. wird dem Argument ein „&“ vorangestellt, damit es beim Funktionsaufruf als Referenz auf die Speicherstelle und nicht einfach als Wert der Variablen benutzt wird (machWas(&arg)). Einen solchen Mechanismus besitzt JavaScript nicht.
Objekte als Argumente übergeben
Wenn Objekte als Argumente an eine Funktion übergeben werden, kann eine call by reference-Mimic durchgeführt werden – d.h., das Objekt wird tatsächlich innerhalb der Funktion geändert und nicht einfach nur sein Wert in Berechnungen verwendet. Ganz so einfach, wie das klingt, ist es dann aber immer noch nicht.
Call by value
let myObj = { val : 1000 }; console.log("Vor dem Aufruf von machWasPerValue " + varObj); function machWasPerValue( arg ) { arg += 3000; console.log("In Funktion machWasPerValue " + arg); } machWasPerValue( myObj.val ); console.log("Nach dem Aufruf von machWasPerValue " + varObj);
Wird der Wert des Objekts (myObj.val) übergeben, und ist der Wert ein primitiver Wert, erfolgt die Übergabe weiterhin als Call by Value, und die Funktion arbeitet auf einer Kopie.
Erst wenn das Objekt selber übergeben wird, entsteht ein Call by Reference und die Funktion ändert die Werte nachhaltig.
Call by reference
let myObj = { val : 1 }; console.log("Vor dem Aufruf von callByReference " + myObj); function callByReference (arg) { arg.val = +100; console.log("In Funktion callByReference " + myObj); } callByReference(myObj); console.log("Nach dem Aufruf von callByReference " + myObj);
Wie Javascript mit den übergebenen Argumenten umgeht, ist nicht immer so strikt, wie wir es von anderen Programmiersprachen her kennen.
Die primitiven Typen wie Number und String werden by value übergeben, aber ein Element vom Typ Object kann sowohl by value als auch by reference übergeben werden.
- Wenn der pure Wert übergeben wird, wird das Argument by value übergeben,
- wird das Objekt übergeben, wird das Argument by reference übergeben.
Call by Sharing
JavaScript nutzt »Call by Sharing«. Objekte werden als Referenz übergeben, aber man kann die Variable selbst nicht ersetzen.
function replaceObject(obj) { obj = { name: "Anna" }; // Neue Referenz! console.log("Innerhalb der Funktion:", obj); } let person = { name: "Thomas" }; replaceObject(person); console.log("Außerhalb der Funktion:", person);
[Log] Innerhalb der Funktion: – {name: "Anna"} [Log] Außerhalb der Funktion: – {name: "Thomas"}
obj = { name: "Anna" } erzeugt eine neue Referenz, die das Original nicht überschreibt. Änderungen am ursprünglichen Objekt funktionieren, aber nicht die komplette Neuzuweisung.
Typ | Call by Value | Call by Reference |
---|---|---|
Primitiv (Number , String , etc.) |
✅ Wird kopiert, Original bleibt gleich | ❌ Nicht möglich |
Objekte & Arrays | ❌ Wird nicht kopiert | ✅ Original wird geändert |
Neuzuweisung in der Funktion | ❌ Keine Auswirkung | ❌ Ändert nicht das Original, sondern nur die lokale Referenz |