Categorie
Javascript Programmazione

{JS} Le variabili e la Scope Chain

Scope Chain;
Global, Local, Function e Block scope;
Automatically Global, dichiarazione implicita delle variabili e use strict;
Let e Clousure.

Cos’è lo scope

La visibilità (in inglese scope), in programmazione, è l’esistenza e la possibilità di richiamare un identificatore, in particolar modo una variabile, in un determinato punto del programma.

Scope Chain

Parlando di scope di una variabile in javascript è un pò come le scatole cinesi: dall’ interno si possono utilizzare le variabili via via più esterne. Questo è il concetto di scope chain.
La Scope Chain è una vera e propria gerarchia di scope.

Global scopevariabile accessibile a livello globale
Local / Function scopevariabili accessibili solo all’interno di una funzione
Block scopevariabili accessibili solo all’interno di un blocco di codice

Global scope

In Javascript le variabili dichiarate fuori da qualsiasi funzione sono dette globali e sono accessibili da qualsiasi punto dello script, anche all’interno di funzioni.

Note: In HTML, l'ambito globale è l'oggetto window.
 Le variabili globali definite con la var parola chiave appartengono all'oggetto finestra.

 var carName = "Volvo";
 // Possiamo richiamarla con window.carName

Local/Function scope

Per deduzione e per logica le variabili contenute all’interno di un determinato ambito “corpo”, per esempio, in una funzione, sono dette locali; ovvero, possono essere richiamate solo ed unicamente al loro interno.

var x = 5;
var y = 10;
fuction nuovaFunzione() {
var z = 5;
x = z + y;
}

x e y sono variabili di tipo globale quindi saranno utilizzabili sia esternamente alla funzione sia internamente ad essa;
z, invece è una variabile di tipo locale, ovvero esiste ed è richiamabili solo ed unicamente all’interno del corpo della funzioni in cui è dichiarata.

Note: Gli argomenti delle funzioni (parametri) funzionano come variabili locali all'interno delle funzioni.
Automatically Global

Se assegni un valore a una variabile che non è stata dichiarata (senza la parola chiave “var”), diventerà automaticamente una variabile GLOBALE .

Questo esempio di codice dichiarerà una variabile globale carName, anche se il valore è assegnato all’interno di una funzione.

function myFunction() {
  carName = "Volvo";
}
Dichiarazione implicita delle variabili

JavaScript non prevede la dichiarazione obbligatoria delle variabili.
Una variabile non dichiarata viene automaticamente creata al primo utilizzo ed è accessibile da qualsiasi punto di uno script.
Essa assumerà qundi il global scope, che sia inzializzata all’esterno o all’interno di una funzione.

use strict

Tutti i browser moderni supportano l’esecuzione di JavaScript in “Modalità rigorosa”.
In “Modalità rigorosa”, le variabili non dichiarate non sono automaticamente globali.

Con la modalità rigorosa, non è quindi possibile, utilizzare variabili non dichiarate.

"use strict";
x = 3.14;       // Restituirà un errore perchè la variabile non è stata dichiarata
function myFunction() {
  y = 3.14;   // Restituirà un errore perchè la variabile non è stata dichiarata
}

Se “use strict” è dichiarato all’inizio di uno script, ha ambito globale, invece, se dichiarato all’interno del blocco di una funzione ha ambito locale.

Note: La modalità rigorosa aggiunge molte altre regole per la sintassi.

Block scope

Prima di ES6 (2015), JavaScript aveva solo Global Scope e Function Scope.
ES6 ha introdotto due nuove importanti parole chiave JavaScript: let e const. Queste due parole chiave forniscono Block Scope in JavaScript.
Un “blocco” è definito attraverso le parentesi graffe {  } e contiene porzioni di codice che sono “a se” rispetto al codice globale (si pensi alle istruzioni “if”, “switch” ecc.)
La differenza più grande ed evidente tra var e let sta proprio nello scope.
Una variabile dichiarata con varnon ha block scope. Questo significa che una variabile dichiarata in un blocco utilizzando var è accessibile anche all’esterno del blocco mentre una variabile dichiarata con let, ha block scope, quindi sarà accessibile e elaborabile solo ed unicamente all’interno del suo blocco contenitore.

let

Se abbiamo bisogno di creare uno scope specifico per una o più variabili possiamo ricorrere all’istruzione let.

Grazie a let dichiariamo ed utilizziamo la variabile soltanto all’interno del blocco di codice, evitando eventuali collisioni con altre variabili omonime definite in scope più esterni

var i = 0;
if (true) {
let i = 1;
}
console.log(i); 

Dichiarando la variabile i con let la variabile sarà con block scope non sarà accessibile all’esterno e console.log non potrà accedervi o meglio accederà alla variabile globale, omonima e accessibile, restituendo il valore 0.

In rete ho trovato questo video di cui allego sotto tutti i riferimenti che spiega abbastanza bene il concetto di scope Global, Local e Block

Autore Achille1789 Fonte: Youtube Link al video

Variabili omonime con scope differente

Si dice che la variabile locale nasconde la variabile globale.

var x = 5;
var y = 10;
fuction nuovaFunzione() {
var x = 20;
z = x + y;
}

Nel caso in cui due variabili siano omonime, come nel caso della variabile “x” la quale viene dichiarata fuori dal blocco fuction, (quindi globale) e sia all’interno del blocco fuction (quindi locale) nel momento in cui richiamata dalla linea di codice ” z = x + y; ” sarà presa in considerazione la variabile con scope locale.
Viene utilizzata la variabile locale, in risoluzione di un ambiguità, in quanto come regola di risoluzione si fa riferimento all’ambito di visibilità più vicino all’utilizzo della variabile.

var x = 5;
var y = 10;
fuction nuovaFunzione() {
var y = x;
var x = 20;
z = x + y;
}

Anche in questo caso dove la variante y viene definita uguale a x, che non è stata ancora dichiarata/inizializzata all’interno funzione, e seppure solo successivamente definita, la x di riferimento sarà sempre quella con scope più vicino alla variabile quindi quella all’interno della funzione.

Closure

La closure è un particolare meccanismo che stabilisce che ogni variabile che era accessibile quando una funzione è stata definita rimane “racchiusa” nello scope accessibile dalla funzione. Questo meccanismo è detto closure.

Ha un enorme potere espressivo e può essere sfruttata in maniera creativa per definire pattern di programmazione evoluta.

Una funzione contenuta in un’altra funzione ha accesso alle variabili della prima.

Costruttori di funzioni

Un costruttore di funzione è un funzione che restituisce una nuova funzione

function funzioneAddizionatrice(x) {
  return function(y) {
    return x + y;
  };
}

var aggiungi5= funzioneAddizionatrice(5);         
//creazione di una funzione che aggiungerà 5 al numero passato 
var aggiungi10= funzioneAddizionatrice(10);     
//creazione di una funzione che aggiungerà 10 al numero passato

console.log(aggiungi5(2));  // 7
console.log(aggiungi10(2)); // 12

Scope di una funzione contenuta in una funzione

var messaggio = "Buongiorno";

var visualizzaSaluto;

function saluta(persona) {
 var nomeEcognome = persona.nome + " " + persona.cognome;
 
                                return function() {
          document.write(messaggio + " " + nomeEcognome);
                          };
}

visualizzaSaluto = saluta({nome: "Mario", cognome: "Rossi"});

visualizzaSaluto();

In questo caso la funzione saluta() restituisce una funzione che si occupa di stampare il messaggio completo. Quando la funzione restituita viene invocata, la funzione saluta() ha terminato la sua esecuzione ed il suo compito e quindi il suo contesto di esecuzione non esiste più.
Nonostante ciò è ancora possibile accedere alla variabile nomeCognome presente nel suo scope locale.

Lascia un commento

Il tuo indirizzo email non sarà pubblicato. I campi obbligatori sono contrassegnati *