Passer par valeur VS. Passer par référence
L'appel par valeur est la stratégie d'évaluation la plus couramment utilisée : les paramètres formels d'une fonction sont des copies des paramètres réels transmis lors de l'appel. La modification de la valeur du paramètre formel n'affecte pas le paramètre réel.
Lors du passage par référence (appel par référence), les paramètres formels de la fonction reçoivent des références implicites aux paramètres réels, plutôt que des copies. Cela signifie que si les valeurs des paramètres de fonction sont modifiées, les paramètres réels seront également modifiés. En même temps, les deux indiquent la même valeur.
Le passage par référence rend plus difficile le traçage des appels de fonction et provoque parfois des bugs subtils.
Le passage par valeur nécessite un clone à chaque fois, les performances sont donc inférieures pour certains types complexes. Les deux méthodes de transmission de valeurs ont leurs propres problèmes.
Regardons d'abord un exemple en C pour comprendre la différence entre le passage par valeur et par référence :
Ici, nous pouvons voir :
a => Lorsque p est passé par valeur, la modification de la valeur du paramètre formel p n'affecte pas le paramètre réel a, qui n'est qu'une copie de a.
b => q est passé par référence. La modification de la valeur du paramètre formel q affecte également la valeur du paramètre réel b.
Découvrez comment les valeurs JS sont transmises
Les types de base de JS sont transmis par valeur.
Regardez à nouveau l'objet :
Expliquez que o et obj sont le même objet et que o n'est pas une copie de obj. Ce n'est donc pas transmis par valeur. Mais cela signifie-t-il que les objets JS sont passés par référence ? Regardons l'exemple suivant :
S'il est passé par référence, la modification de la valeur du paramètre formel o devrait affecter le paramètre réel. Mais modifier la valeur de o ici n'affecte pas obj. Par conséquent, les objets dans JS ne sont pas transmis par référence. Alors, comment la valeur de l’objet est-elle transférée dans JS ?
appelle en partageant
Pour être précis, les types de base en JS sont transmis par valeur et les types d'objets sont transmis par partage (appel par partage, également appelé passage par objet et passage par partage d'objet). Il a été proposé pour la première fois par Barbara Liskov dans le langage GLU en 1974. Cette stratégie d'évaluation est utilisée en Python, Java, Ruby, JS et d'autres langages.
Le point clé de cette stratégie est le suivant : lors de l'appel d'une fonction pour passer des paramètres, la fonction accepte une copie de la référence de l'argument de l'objet (ni une copie de l'objet passé par valeur, ni une référence implicite passée par référence). La différence entre celui-ci et le passage par référence est que l'affectation des paramètres de fonction dans le transfert partagé n'affectera pas la valeur du paramètre réel. Comme dans l'exemple suivant, la valeur de obj ne peut pas être modifiée en modifiant la valeur du paramètre formel o.
Cependant, bien que la référence soit une copie, l'objet référencé est le même. Ils partagent le même objet, donc la modification des valeurs de propriété de l'objet paramètre formel affectera également les valeurs de propriété des paramètres réels.
Pour les types d'objet, puisque l'objet est mutable, la modification de l'objet lui-même affectera les références et les copies de référence qui partagent l'objet. Quant aux types de base, puisqu'ils sont tous immuables, il n'y a aucune différence entre le passage par partage et le passage par valeur (appel par valeur). Par conséquent, les types de base JS sont conformes à la fois au passage par valeur et au passage par partage.
var a = 1; // 1 est un type numérique, immuable var b = a = 6;
Selon la stratégie d'évaluation passe par action, a et b sont deux références différentes (b est une copie de référence de a), mais font référence à la même valeur. Puisque le type de base numéro 1 est ici immuable, il n'y a aucune différence entre le passage par valeur et le passage par partage.
La nature immuable des types de base
Les types de base sont immuables (immuables), seuls les objets sont mutables (mutables). Par exemple, la valeur numérique 100, la valeur booléenne vrai, faux, en modifiant ces valeurs (comme changer 1 en 3, changer vrai en 100). ) ne le fait pas. Quelle est la signification. Ce qui est plus facile à mal comprendre, c'est la chaîne en JS. Parfois, nous essayons de « modifier » le contenu d’une chaîne, mais en JS, toute opération qui semble « modifier » une valeur de chaîne crée en réalité une nouvelle valeur de chaîne.
Mais les objets sont différents, les objets sont mutables.
Définissez ici la variable obj, la valeur est object, puis définissez la valeur de l'attribut obj.x sur 100. Définissez ensuite une autre variable o, dont la valeur est toujours l'objet objet. A ce moment, les valeurs des deux variables obj et o pointent vers le même objet (partagent une référence au même objet). Par conséquent, modifier le contenu de l’objet affectera à la fois obj et o. Mais l'objet n'est pas passé par référence. La valeur de o est modifiée par o = true, ce qui n'affectera pas obj.