English | 简体中文 | 繁體中文 | Русский язык | Français | Español | Português | Deutsch | 日本語 | 한국어 | Italiano | بالعربية
Sembra che in pochi parliano di riferimenti e copie in JavaScript, ma chiarire questa concezione può aiutare a comprendere molte cose
Parliamo prima di cose molto basilari, vediamo quali tipi di dati passano in JavaScript
Riferimento: oggetti, array, funzioni
Copia: numeri, booleani
Le stringhe sono trattate separatamente a causa della loro particolarità, non è possibile determinare se si passa un riferimento o una copia del valore (poiché il valore delle stringhe non può essere modificato, è senza senso preoccuparsi di questo problema) ma ovviamente si tratta di confronti per valore (più avanti parleremo specificamente dei confronti)
Di seguito, vediamo come si manifestano concretamente durante l'uso
L'uso più comune è l'assegnazione
var a = 1; var b = a; // Assegna il valore copiato di a b ++; alert(a); //"1" Le modifiche a b non influenzano a /****************************************/ var a = [1]; var b = a; // Assegna il riferimento di a b[0] ++; alert(a); //"2" Le modifiche a b sono efficaci per a Tuttavia, naturalmente, b = [2]; questa modifica non è utile per a.
Parametri della funzione
Passaggio per valore: L'argomento passato alla funzione è una copia del valore, le modifiche fatte alla funzione non sono visibili dall'esterno
var a = 1; var b = 2; function change(a,b) { var c = a; a = b; //Overwriting con una nuova riferimento b = c; alert(a); //"2" alert(b); //"1" }; change(a,b); alert(a); //"1" alert(b); //"2"
Passaggio per riferimento:L'argomento passato alla funzione è un riferimento a un valore, le modifiche alle sue proprietà sono visibili dall'esterno della funzione, ma se lo sostituiamo con un nuovo riferimento, non è visibile dall'esterno, ad esempio
var a = [1, 2, 3]; var b = [5, 6]; function change(a,b) { a[0] = 4; //Le modifiche alle proprietà sono visibili dall'esterno var c = a; a = b; //Overwriting con una nuova riferimento b = c; alert(a); //"5,6" alert(b); //"4,2,3" }; change(a,b); alert(a); //"4,2,3" alert(b); //"5,6"
Dal risultato possiamo vedere che a e b non sono stati scambiati, perché l'overwriting con una nuova riferimento non è visibile dall'esterno, questo è molto naturale perché la funzione ha solo preso il riferimento e non ha il potere di cambiare il riferimento.
Ecco un caso diverso
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"
Ecco che l'interscambio è stato realizzato con successo
Anche qui dobbiamo parlare dell'ambito a livelli di blocco del JavaScript, che sarebbe sicuramente segnalato come errore di definizione in alcuni linguaggi, perché il JavaScript non ha l'ambito a livelli di blocco, quindi quando non trova le variabili a, b all'interno di change, si dirigerà automaticamente verso il livello superiore, quindi qui a, b sono riferimenti di variabili globali.
E quei variabili a, b sopra sono variabili nella funzione change, quando si chiama la funzione, il riferimento di a, b è assegnato a queste variabili, ma non può cambiare a, b nel contesto globale, cambiare il nome può rendere la comprensione più chiara.
Questa è una piccola menzione, un po' fuori argomento...
Torniamo all'attenzione del confronto per riferimento e copia.
Il confronto per valore confronta i numeri, mentre il confronto per riferimento confronta i riferimenti, anche se i numeri sono gli stessi, i riferimenti diversi non sono uguali.
1 == 1; //true 1 === 1; //true [0] == [0]; //false [0][0] == [0][0]; //true [0][0] === [0][0]; //true [0].toString() == [0].toString(); //true
All'interno dei closure...
I closure sono probabilmente le cose più complicate nel JavaScript, sono la domanda classica delle interviste nel nostro dipartimento, sempre popolare...
Prima di parlare delle cose dei closure, parliamo solo della parte che riguarda il passaggio di valore e il riferimento, quando sarò in grado di spiegare chiaramente quella cosa con regole chiare, linguaggio chiaro e esempi vivi, allora descriverò in dettaglio questo tipo di cosa che non può essere trascurato nel JavaScript...
All'interno dei closure, le funzioni interne utilizzano i variabili locali delle funzioni esterne tramite riferimento invece di copia.
In realtà, questa è anche una parte molto importante per comprendere i closure, può essere utilizzata per spiegare un fenomeno di closure molto classico, un esempio che spesso viene utilizzato per spiegare i closure in molte parti.
/*Costruire una funzione, impostare il gestore degli eventi degli elementi dell'array, quando si clicca su un elemento, alert il numero di sequenza dell'elemento*/ var add_handlers = function (nodes) { var i; for (i = 0, l = nodes.length; i < l; i++) { nodes[i].onclick = function (e) { alert(i); // Naturalmente, il risultato qui è che ogni volta che alert è il numero totale dei nodi... }; }; };
Perché ogni volta che alert è il numero totale dei nodi invece del numero di ordine previsto? Questo è spiegabile facilmente con copia e riferimento
Poiché le funzioni interne utilizzano il riferimento alle variabili esterne invece della copia, voglio dire che quando assegniamo l'evento onclick a ogni nodo, passiamo la riferimento di i a alert, quando clicchiamo sul nodo e si attiva l'evento onclick, il valore di i è diventato il numero totale dei nodi...
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); }; };
Il motivo per cui questa modifica è corretta è perché ora si passinga una copia del valore di i, è esattamente come una funzione normale, non vi lasciate ingannare dal fatto che c'è una closure, tornate al principio per riflettere e capire, il principio è proprio il passaggio per riferimento che ho menzionato prima
Per inciso, non lasciatevi intimidire dal nome strano di closure, in realtà è lo stesso principio dei funzioni che usiamo ogni giorno, mettiamo da parte quei presunti tratti di closure come 'più lungo ciclo di vita' e 'protezione delle variabili private', e trattiamolo come una funzione normale (o possiamo anche vedere la funzione globale come un closure speciale), è facile capirlo
La chiave è lasciare da parte tutte le lusinghe, tornare all'essenza... mi sono perso di strada di nuovo...
Questo breve saggio sull'uso di riferimento e copia (passaggio per valore e passaggio per riferimento) in JavaScript è tutto ciò che il nostro autore ha condiviso con voi, speriamo che possa essere utile come riferimento e che speriamo che possiate supportare Tutorial di grido.