Meine zwei Cent ... So verstehe ich es. (Fühlen Sie sich frei, mich zu korrigieren, wenn ich falsch liege)
Es ist Zeit, alles, was Sie über Pass by Value / Reference wissen, wegzuwerfen.
Denn in JavaScript spielt es keine Rolle, ob es als Wert oder als Referenz oder was auch immer übergeben wird. Was zählt, ist die Mutation gegen die Zuordnung der an eine Funktion übergebenen Parameter.
OK, lassen Sie mich mein Bestes geben, um zu erklären, was ich meine. Angenommen, Sie haben einige Objekte.
var object1 = {};
var object2 = {};
Was wir getan haben, ist "Zuweisung" ... Wir haben den Variablen "Objekt1" und "Objekt2" 2 separate leere Objekte zugewiesen.
Nehmen wir nun an, wir mögen object1 besser ... Also "weisen" wir eine neue Variable zu.
var favoriteObject = object1;
Als nächstes entscheiden wir aus irgendeinem Grund, dass uns Objekt 2 besser gefällt. Also machen wir einfach eine kleine Neuzuweisung.
favoriteObject = object2;
Objekt1 oder Objekt2 ist nichts passiert. Wir haben überhaupt keine Daten geändert. Wir haben lediglich neu zugewiesen, was unser Lieblingsobjekt ist. Es ist wichtig zu wissen, dass Objekt2 und Favoritenobjekt beide demselben Objekt zugewiesen sind. Wir können dieses Objekt über eine dieser Variablen ändern.
object2.name = 'Fred';
console.log(favoriteObject.name) // Logs Fred
favoriteObject.name = 'Joe';
console.log(object2.name); // Logs Joe
OK, jetzt schauen wir uns Primitive wie zum Beispiel Strings an
var string1 = 'Hello world';
var string2 = 'Goodbye world';
Wieder wählen wir einen Favoriten.
var favoriteString = string1;
Sowohl unsere Favoriten-Variablen stringString als auch string1 sind 'Hello world' zugeordnet. Was ist, wenn wir unseren Favoriten ändern wollen? Was wird passieren???
favoriteString = 'Hello everyone';
console.log(favoriteString); // Logs 'Hello everyone'
console.log(string1); // Logs 'Hello world'
Oh oh ... was ist passiert? Wir konnten string1 nicht ändern, indem wir favorString geändert haben ... Warum? Weil wir unser String- Objekt nicht geändert haben . Alles, was wir getan haben, war "RE ASSIGN", die Variable "avorString " für einen neuen String. Dies trennte es im Wesentlichen von string1. Im vorherigen Beispiel haben wir beim Umbenennen unseres Objekts nichts zugewiesen. (Nun, nicht der Variablen selbst , ... wir haben jedoch die Eigenschaft name einer neuen Zeichenfolge zugewiesen.) Stattdessen haben wir einfach das Objekt mutiert, das die Verbindungen zwischen den beiden Variablen und den zugrunde liegenden Objekten beibehält. (Auch wenn wir das String-Objekt selbst ändern oder mutieren wollten, konnten wir nicht haben, weil Strings in JavaScript tatsächlich unveränderlich sind.)
Nun zu Funktionen und Übergabe von Parametern ... Wenn Sie eine Funktion aufrufen und einen Parameter übergeben, tun Sie im Wesentlichen eine "Zuweisung" zu einer neuen Variablen, und dies funktioniert genauso, als ob Sie einfach mit zugewiesen hätten das Gleichheitszeichen (=).
Nehmen Sie diese Beispiele.
var myString = 'hello';
// Assign to a new variable (just like when you pass to a function)
var param1 = myString;
param1 = 'world'; // Re assignment
console.log(myString); // Logs 'hello'
console.log(param1); // Logs 'world'
Nun das Gleiche, aber mit einer Funktion
function myFunc(param1) {
param1 = 'world';
console.log(param1); // Logs 'world'
}
var myString = 'hello';
// Calls myFunc and assigns param1 to myString just like param1 = myString
myFunc(myString);
console.log(myString); // logs 'hello'
OK, jetzt geben wir ein paar Beispiele, die stattdessen Objekte verwenden ... zuerst ohne die Funktion.
var myObject = {
firstName: 'Joe',
lastName: 'Smith'
};
// Assign to a new variable (just like when you pass to a function)
var otherObj = myObject;
// Let's mutate our object
otherObj.firstName = 'Sue'; // I guess Joe decided to be a girl
console.log(myObject.firstName); // Logs 'Sue'
console.log(otherObj.firstName); // Logs 'Sue'
// Now, let's reassign the variable
otherObj = {
firstName: 'Jack',
lastName: 'Frost'
};
// Now, otherObj and myObject are assigned to 2 very different objects
// And mutating one object has no influence on the other
console.log(myObject.firstName); // Logs 'Sue'
console.log(otherObj.firstName); // Logs 'Jack';
Nun das Gleiche, aber mit einem Funktionsaufruf
function myFunc(otherObj) {
// Let's mutate our object
otherObj.firstName = 'Sue';
console.log(otherObj.firstName); // Logs 'Sue'
// Now let's re-assign
otherObj = {
firstName: 'Jack',
lastName: 'Frost'
};
console.log(otherObj.firstName); // Logs 'Jack'
// Again, otherObj and myObject are assigned to 2 very different objects
// And mutating one object doesn't magically mutate the other
}
var myObject = {
firstName: 'Joe',
lastName: 'Smith'
};
// Calls myFunc and assigns otherObj to myObject just like otherObj = myObject
myFunc(myObject);
console.log(myObject.firstName); // Logs 'Sue', just like before
OK, wenn Sie diesen gesamten Beitrag durchlesen, haben Sie jetzt vielleicht ein besseres Verständnis dafür, wie Funktionsaufrufe in JavaScript funktionieren. Es spielt keine Rolle, ob etwas als Referenz oder als Wert übergeben wird ... Was zählt, ist Zuordnung gegen Mutation.
Jedes Mal, wenn Sie eine Variable an eine Funktion übergeben, "weisen" Sie dem Namen der Parametervariablen "zu", genau wie wenn Sie das Gleichheitszeichen (=) verwendet haben.
Denken Sie immer daran, dass das Gleichheitszeichen (=) Zuweisung bedeutet. Denken Sie immer daran, dass das Übergeben eines Parameters an eine Funktion in JavaScript auch eine Zuweisung bedeutet. Sie sind gleich und die beiden Variablen sind genau gleich miteinander verbunden (dh sie sind es nicht, es sei denn, Sie zählen, dass sie demselben Objekt zugewiesen sind).
Das "Ändern einer Variablen" wirkt sich nur dann auf eine andere Variable aus, wenn das zugrunde liegende Objekt mutiert ist (in diesem Fall haben Sie nicht die Variable, sondern das Objekt selbst geändert.
Es macht keinen Sinn, zwischen Objekten und Grundelementen zu unterscheiden, da dies genauso funktioniert, als ob Sie keine Funktion hätten und nur das Gleichheitszeichen verwendet hätten, um einer neuen Variablen zuzuweisen.
Das einzige Problem ist, wenn der Name der Variablen, die Sie an die Funktion übergeben, mit dem Namen des Funktionsparameters übereinstimmt. In diesem Fall müssen Sie den Parameter in der Funktion so behandeln, als wäre er eine ganz neue Variable, die für die Funktion privat ist (weil dies der Fall ist).
function myFunc(myString) {
// myString is private and does not affect the outer variable
myString = 'hello';
}
var myString = 'test';
myString = myString; // Does nothing, myString is still 'test';
myFunc(myString);
console.log(myString); // Logs 'test'