English | 简体中文 | 繁體中文 | Русский язык | Français | Español | Português | Deutsch | 日本語 | 한국어 | Italiano | بالعربية
Il semble que peu de gens parlent de la référence et de la copie en JavaScript, mais comprendre cette conception peut aider à comprendre beaucoup de choses
Parlons d'abord des choses très basiques, voyons quels types de données sont transmis en JavaScript
Référence : objets, tableaux, fonctions
Copie : nombres, booléens
Les chaînes de caractères doivent être expliquées séparément, car elles sont spéciales, il est impossible de déterminer s'il s'agit de la transmission de la référence ou de la copie de la valeur (puisque la valeur des chaînes de caractères ne peut pas être modifiée, il n'a pas de sens de se poser cette question) mais évidemment, lors de la comparaison, elles appartiennent à la comparaison par valeur (nous en parlerons plus en détail plus tard)
Voici quelques exemples spécifiques de son utilisation
L'utilisation la plus courante est l'affectation
var a = 1; var b = a; //Il s'agit de la copie de a b ++; alert(a); //"1"La modification de b n'affecte pas a /****************************************/ var a = [1} var b = a; //Il s'agit de la référence de a b[0] ++; alert(a); //"2"La modification de b est également applicable à a, mais bien sûr b = [2];Ces modifications ne sont pas utiles pour a.
Paramètres de la fonction
Transmission de valeurs : la transmission à la fonction est une copie de nombre. Les modifications de cette valeur sont invisibles à l'extérieur
var a = 1; var b = 2; function change(a,b) { var c = a; a = b; //Remplacement de la nouvelle référence b = c; alert(a); //"2" alert(b); //"1" }; change(a,b); alert(a); //"1" alert(b); //"2"
Transmission par adresse :Transmission de références : la transmission à la fonction est une référence de nombre. Les modifications de ses attributs sont visibles à l'extérieur, mais le remplacement de la nouvelle référence est invisible à l'extérieur, par exemple
var a = [1, 2, 3} var b = [5, 6} function change(a,b) { a[0] = 4; //Les modifications des attributs sont visibles à l'extérieur var c = a; a = b; //Remplacement de la nouvelle référence b = c; alert(a); //"5,6" alert(b); //"4,2,3" }; change(a,b); alert(a); //"4,2,3" alert(b); //"5,6"
D'après les résultats, a et b ne sont pas échangés. Parce que la nouvelle référence couvre l'extérieur qui est invisible. C'est naturel, car la fonction ne peut pas modifier la référence et n'a pas le pouvoir de le faire.
Ce n'est pas le cas ici
var a = [1, 2, 3} var b = [5, 6} function change() { var c = a; a[0] = 4; a = b; b = c; }; change(); alert(a); //"5,6" alert(b); //"4,2,3"
L'échange a été réussi
Encore une fois, mentionnons le domaine d'application des scopes de blocs en JS. Dans certains langages, cela entraînerait une erreur de variable non définie, car JS n'a pas de scope de bloc. Par conséquent, lorsque change ne trouve pas les variables a, b, il va automatiquement chercher au niveau supérieur. Donc, ici, a, b sont des références de variables globales
Et pour le cas de l'a, b ci-dessus, ce sont des variables de la fonction change. Lors de l'appel de la fonction, la référence de a, b est assignée à ces deux variables. Cependant, cela ne peut pas changer a, b dans le contexte global. Changer de nom pourrait rendre cela plus clair...
Je vais juste mentionner cela rapidement, cela s'éloigne un peu du sujet...
Retour à la comparaison de références et de copies, voici les points à noter lors des opérations de comparaison
La comparaison de valeurs transmises compare des nombres, tandis que la comparaison de références transmises compare des références. Deux références différentes sont égales même si les valeurs sont les mêmes.
1 == 1; //true 1 === 1; //true [0] == [0]; //false [0][0] == [0][0]; //true [0][0] === [0][0]; //true [0].toString() == [0].toString(); //true
Dans les closures...
Les closures sont probablement l'une des choses les plus complexes en JS. C'est une question classique de l'entretien d'embauche de notre département, toujours populaire...
Ici, je ne parle pas encore des choses des closures, mais plutôt des parties impliquant la transmission de valeurs et les références. Jusqu'au jour où je pourrai expliquer clairement cette chose avec des règles claires, un langage simple et des exemples vivants, je donnerai une explication détaillée de ce qui est incontournable dans JS...
Dans les closures, la fonction interne utilise les variables locales de la fonction externe de manière référencée plutôt que de les copier.
En réalité, c'est aussi une partie très importante pour comprendre les closures. On peut l'utiliser pour expliquer un phénomène classique des closures, un exemple souvent utilisé pour expliquer les closures.
/*Construisez une fonction, configurez les gestionnaires d'événements pour les éléments d'un tableau, alertez le numéro de l'élément lorsque vous cliquez sur un élément*/ var add_handlers = function (nodes) { var i; for (i = 0, l = nodes.length; i < l; i ++) { nodes[i].onclick = function (e) { alert(i); // Bien sûr, le résultat ici est nécessairement que l'alerte soit toujours le nombre total de noeuds chaque fois... }; }; };
Pourquoi alerte-t-on toujours le nombre total de noeuds au lieu du numéro attendu ? Cela peut être expliqué très facilement en termes de copie et de référence
Parce que les fonctions internes utilisent le mode de référence pour utiliser les variables externes au lieu de la copie, c'est-à-dire que lorsque je configure l'événement onclick pour chaque noeud, je transmets la référence de i à l'alerte. Lorsque je clique sur le noeud pour déclencher l'événement onclick, la valeur de i a déjà été modifiée en nombre total de noeuds...
var add_handlers = function (nodes) { var i; for (i = 0, l = nodes.length; i < l; i ++) { nodes[i].onclick = function (i) { return function() { alert(i); }; }(i); }; };
La raison pour laquelle cette modification est correcte est que, à ce moment, c'est une copie de la valeur de i qui est transmise, c'est en réalité la même chose que pour une fonction ordinaire. Ne vous laissez pas brouiller par la closure, retournez à l'origine pour réfléchir et vous comprendrez, l'origine est la transmission d'adresse que nous avons mentionnée précédemment
D'ailleurs, ne soyez pas effrayé par ce nom bizarre de closure, en réalité, c'est la même chose que les fonctions que nous utilisons dans la vie quotidienne. Abandonnons les
L'essentiel est de mettre de côté toutes les vanités, de revenir à l'essence... Je m'éloigne à nouveau du sujet...
Les quelques mots que j'ai partagés ici sur les références et les copies dans JavaScript (transmission de valeur et d'adresse) sont tout ce que je peux partager avec vous. J'espère que cela vous sera utile et que vous continuerez à soutenir le tutoriel de cri.