I miei due centesimi ... Questo è il modo in cui lo capisco. (Sentiti libero di correggermi se sbaglio)
È tempo di buttare via tutto ciò che sai sul passaggio per valore / riferimento.
Perché in JavaScript, non importa se viene passato per valore o per riferimento o altro. Ciò che conta è la mutazione vs assegnazione dei parametri passati in una funzione.
OK, lasciami fare del mio meglio per spiegare cosa intendo. Diciamo che hai alcuni oggetti.
var object1 = {};
var object2 = {};
Quello che abbiamo fatto è "assegnazione" ... Abbiamo assegnato 2 oggetti vuoti separati alle variabili "oggetto1" e "oggetto2".
Ora, diciamo che ci piace meglio object1 ... Quindi, "assegniamo" una nuova variabile.
var favoriteObject = object1;
Successivamente, per qualsiasi motivo, decidiamo che ci piace meglio l'oggetto 2. Quindi, facciamo semplicemente un piccolo riassegnazione.
favoriteObject = object2;
Non è successo nulla all'oggetto1 o all'oggetto2. Non abbiamo modificato alcun dato. Tutto ciò che abbiamo fatto è stato riassegnare il nostro oggetto preferito. È importante sapere che object2 e favoriteObject sono entrambi assegnati allo stesso oggetto. Possiamo cambiare quell'oggetto tramite una di quelle variabili.
object2.name = 'Fred';
console.log(favoriteObject.name) // Logs Fred
favoriteObject.name = 'Joe';
console.log(object2.name); // Logs Joe
OK, ora diamo un'occhiata alle primitive come le stringhe per esempio
var string1 = 'Hello world';
var string2 = 'Goodbye world';
Ancora una volta, scegliamo un preferito.
var favoriteString = string1;
Entrambe le nostre variabili favoriteString e string1 sono assegnate a "Hello world". E se volessimo cambiare la nostra stringa preferita ??? Cosa accadrà???
favoriteString = 'Hello everyone';
console.log(favoriteString); // Logs 'Hello everyone'
console.log(string1); // Logs 'Hello world'
Uh oh .... Cosa è successo. Non abbiamo potuto cambiare string1 cambiando favoriteString ... Perché ?? Perché non abbiamo cambiato il nostro oggetto stringa . Tutto ciò che abbiamo fatto è stato "RE ASSIGN" la variabile favoriteString in una nuova stringa. Questo essenzialmente lo ha disconnesso da string1. Nell'esempio precedente, quando abbiamo rinominato il nostro oggetto, non abbiamo assegnato nulla. (Beh, non alla variabile stessa , ... tuttavia, abbiamo assegnato la proprietà name a una nuova stringa.) Invece, abbiamo semplicemente mutato l'oggetto che mantiene le connessioni tra le 2 variabili e gli oggetti sottostanti. (Anche se avessimo voluto modificare o mutare l'oggetto stringa stesso , non avremmo potuto, perché le stringhe sono in realtà immutabili in JavaScript.)
Ora, passiamo alle funzioni e passiamo i parametri .... Quando chiami una funzione e passi un parametro, quello che stai essenzialmente facendo è un "incarico" a una nuova variabile, e funziona esattamente come se ti assegnassi semplicemente usando il segno uguale (=).
Prendi questi esempi.
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'
Ora, la stessa cosa, ma con una funzione
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, ora diamo alcuni esempi usando gli oggetti invece ... prima, senza la funzione.
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';
Ora, la stessa cosa, ma con una chiamata di funzione
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, se leggi tutto questo post, forse ora hai una migliore comprensione di come funzionano le chiamate di funzione in JavaScript. Non importa se qualcosa viene passato per riferimento o per valore ... Ciò che conta è assegnazione vs mutazione.
Ogni volta che passi una variabile a una funzione, stai "assegnando" a qualunque sia il nome della variabile parametro, proprio come se avessi usato il segno uguale (=).
Ricorda sempre che il segno di uguale (=) significa assegnazione. Ricorda sempre che passare un parametro a una funzione in JavaScript significa anche assegnare. Sono uguali e le 2 variabili sono collegate esattamente allo stesso modo (vale a dire che non lo sono, a meno che non si contino che sono assegnate allo stesso oggetto).
L'unica volta in cui "la modifica di una variabile" influenza una variabile diversa è quando l'oggetto sottostante viene mutato (nel qual caso non è stata modificata la variabile, ma l'oggetto stesso.
Non ha senso fare una distinzione tra oggetti e primitive, perché funziona esattamente come se non si avesse una funzione e si utilizzasse semplicemente il segno uguale per assegnare a una nuova variabile.
L'unico gotcha è quando il nome della variabile che passi nella funzione è uguale al nome del parametro della funzione. Quando ciò accade, devi trattare il parametro all'interno della funzione come se fosse una variabile completamente nuova privata alla funzione (perché lo è)
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'