Mes deux cents ... C'est ainsi que je le comprends. (N'hésitez pas à me corriger si je me trompe)
Il est temps de jeter tout ce que vous savez sur le passage par valeur / référence.
Parce qu'en JavaScript, peu importe qu'il soit passé par valeur ou par référence ou autre. Ce qui compte, c'est la mutation vs l'affectation des paramètres passés dans une fonction.
OK, laissez-moi faire de mon mieux pour expliquer ce que je veux dire. Disons que vous avez quelques objets.
var object1 = {};
var object2 = {};
Ce que nous avons fait, c'est "affectation" ... Nous avons affecté 2 objets vides séparés aux variables "objet1" et "objet2".
Maintenant, disons que nous aimons mieux object1 ... Donc, nous "assignons" une nouvelle variable.
var favoriteObject = object1;
Ensuite, pour une raison quelconque, nous décidons que nous aimons mieux l'objet 2. Donc, nous faisons simplement une petite réaffectation.
favoriteObject = object2;
Rien n'est arrivé à object1 ou à object2. Nous n'avons modifié aucune donnée. Tout ce que nous avons fait, c'est de réaffecter notre objet préféré. Il est important de savoir que object2 et favoriteObject sont tous deux affectés au même objet. Nous pouvons changer cet objet via l'une de ces variables.
object2.name = 'Fred';
console.log(favoriteObject.name) // Logs Fred
favoriteObject.name = 'Joe';
console.log(object2.name); // Logs Joe
OK, regardons maintenant les primitives comme les chaînes par exemple
var string1 = 'Hello world';
var string2 = 'Goodbye world';
Encore une fois, nous choisissons un favori.
var favoriteString = string1;
Nos variables favoriteString et string1 sont affectées à «Hello world». Et maintenant, si nous voulons changer notre chaîne favorite ??? Que va-t-il se passer ???
favoriteString = 'Hello everyone';
console.log(favoriteString); // Logs 'Hello everyone'
console.log(string1); // Logs 'Hello world'
Euh oh .... Qu'est-ce qui s'est passé. Nous ne pouvions pas changer string1 en changeant favoriteString ... Pourquoi ?? Parce que nous n'avons pas changé notre objet chaîne . Tout ce que nous avons fait, c'est "RE ASSIGNER" la variable favoriteString à une nouvelle chaîne. Cela l'a essentiellement déconnecté de string1. Dans l'exemple précédent, lorsque nous avons renommé notre objet, nous n'avons rien attribué. (Eh bien, pas à la variable elle - même , ... nous avons cependant assigné la propriété name à une nouvelle chaîne.) Au lieu de cela, nous avons simplement muté l'objet qui conserve les connexions entre les 2 variables et les objets sous-jacents. (Même si nous avions voulu modifier ou muter l'objet chaîne lui-même, nous ne pourrions pas l'avoir, car les chaînes sont en fait immuables en JavaScript.)
Passons maintenant aux fonctions et à la transmission de paramètres .... Lorsque vous appelez une fonction et passez un paramètre, ce que vous faites essentiellement est une "affectation" à une nouvelle variable, et cela fonctionne exactement de la même manière que si vous l'attribuiez simplement à l'aide de le signe égal (=).
Prenez ces exemples.
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'
Maintenant, la même chose, mais avec une fonction
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, donnons maintenant quelques exemples en utilisant des objets à la place ... d'abord, sans la fonction.
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';
Maintenant, la même chose, mais avec un appel de fonction
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, si vous lisez l'intégralité de cet article, vous avez peut-être maintenant une meilleure compréhension du fonctionnement des appels de fonction en JavaScript. Peu importe que quelque chose soit passé par référence ou par valeur ... Ce qui compte, c'est l'affectation vs la mutation.
Chaque fois que vous passez une variable à une fonction, vous "assignez" à quelque soit le nom de la variable de paramètre, comme si vous utilisiez le signe égal (=).
Rappelez-vous toujours que le signe égal (=) signifie affectation. Souvenez-vous toujours que passer un paramètre à une fonction en JavaScript signifie également une affectation. Ils sont identiques et les 2 variables sont connectées exactement de la même manière (c'est-à-dire qu'elles ne le sont pas, sauf si vous comptez qu'elles sont affectées au même objet).
Le seul moment où la "modification d'une variable" affecte une variable différente est lorsque l'objet sous-jacent est muté (auquel cas vous n'avez pas modifié la variable, mais l'objet lui-même.
Il est inutile de faire une distinction entre les objets et les primitives, car cela fonctionne exactement de la même manière que si vous n'aviez pas de fonction et que vous utilisiez simplement le signe égal pour attribuer à une nouvelle variable.
Le seul problème est que le nom de la variable que vous passez dans la fonction est le même que le nom du paramètre de fonction. Lorsque cela se produit, vous devez traiter le paramètre à l'intérieur de la fonction comme s'il s'agissait d'une toute nouvelle variable privée de la fonction (car elle l'est)
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'