Qual è lo scopo delle variabili in JavaScript?

Qual è lo scopo delle variabili in javascript? Hanno lo stesso scopo all’interno piuttosto che all’esterno di una funzione? O importa anche? Inoltre, dove sono memorizzate le variabili se sono definite globalmente?

Penso che il meglio che posso fare sia darti un sacco di esempi da studiare. I programmatori di Javascript sono praticamente classificati in base alla loro comprensione dell’ambito. A volte può essere abbastanza contro-intuitivo.

  1. Una variabile con ambito globale

    // global scope var a = 1; function one() { alert(a); // alerts '1' } 
  2. Ambito locale

     // global scope var a = 1; function two(a) { // passing (a) makes it local scope alert(a); // alerts the given argument, not the global value of '1' } // local scope again function three() { var a = 3; alert(a); // alerts '3' } 
  3. Intermedio : non esiste lo scope block in JavaScript (ES5; ES6 introduce let )

    un.

     var a = 1; function four() { if (true) { var a = 4; } alert(a); // alerts '4', not the global value of '1' } 

    b.

     var a = 1; function one() { if (true) { let a = 4; } alert(a); // alerts '1' because the 'let' keyword uses block scoping } 
  4. Intermedio : proprietà dell’object

     var a = 1; function Five() { this.a = 5; } alert(new Five().a); // alerts '5' 
  5. Avanzato : chiusura

     var a = 1; var six = (function() { var a = 6; return function() { // JavaScript "closure" means I have access to 'a' in here, // because it is defined in the function in which I was defined. alert(a); // alerts '6' }; })(); 
  6. Avanzato : risoluzione dell’ambito basata su prototipo

     var a = 1; function seven() { this.a = 7; } // [object].prototype.property loses to // [object].property in the lookup chain. For example... // Won't get reached, because 'a' is set in the constructor above. seven.prototype.a = -1; // Will get reached, even though 'b' is NOT set in the constructor. seven.prototype.b = 8; alert(new seven().a); // alerts '7' alert(new seven().b); // alerts '8' 

  7. Global + Local : un caso particolarmente complesso

     var x = 5; (function () { console.log(x); var x = 10; console.log(x); })(); 

    Questo verrà stampato undefined e 10 anziché 5 e 10 poiché JavaScript sposta sempre le dichiarazioni variabili (non le inizializzazioni) nella parte superiore dello scope, rendendo il codice equivalente a:

     var x = 5; (function () { var x; console.log(x); x = 10; console.log(x); })(); 
  8. Variabile con scope della clausola catch

     var e = 5; console.log(e); try { throw 6; } catch (e) { console.log(e); } console.log(e); 

    Questo verrà stampato 5 , 6 , 5 . All’interno della clausola catch, ombreggia le variabili globali e locali. Ma questo ambito speciale è solo per la variabile catturata. Se scrivi var f; all’interno della clausola catch, quindi è esattamente come se lo aveste definito prima o dopo il blocco try-catch.

Javascript utilizza le catene di ambito per stabilire l’ambito di una determinata funzione. In genere esiste un ambito globale e ogni funzione definita ha il proprio ambito nidificato. Qualsiasi funzione definita all’interno di un’altra funzione ha un ambito locale che è collegato alla funzione esterna. È sempre la posizione nella sorgente che definisce l’ambito.

Un elemento nella catena dell’ambito è fondamentalmente una mappa con un puntatore all’ambito principale.

Quando si risolve una variabile, javascript inizia dall’ambito più interno e ricerca all’esterno.

Le variabili dichiarate globalmente hanno un ambito globale. Le variabili dichiarate all’interno di una funzione hanno lo scopo di tale funzione e le variabili globali shadow con lo stesso nome.

(Sono sicuro che ci sono molte sottigliezze che i veri programmatori JavaScript saranno in grado di evidenziare in altre risposte.In particolare, mi sono imbattuto in questa pagina su cosa significa esattamente in qualsiasi momento. Speriamo che questo link introduttivo sia sufficiente per iniziare anche se.)

JavaScript della vecchia scuola

Tradizionalmente, JavaScript ha solo due tipi di scope:

  1. Ambito globale : le variabili sono note in tutta l’applicazione, dall’inizio dell’applicazione (*)
  2. Ambito funzionale : le variabili sono note all’interno della funzione in cui sono dichiarate, dall’inizio della funzione (*)

Non lo spiegherò, poiché ci sono già molte altre risposte che spiegano la differenza.


JavaScript moderno

Le specifiche JavaScript più recenti ora consentono anche un terzo ambito:

  1. Block Scope : le variabili sono note all’interno del blocco in cui sono dichiarate, dal momento in cui sono dichiarate in poi (**)

Come posso creare variabili per scope di blocco?

Tradizionalmente, crei le tue variabili in questo modo:

 var myVariable = "Some text"; 

Le variabili degli scope di blocco sono create in questo modo:

 let myVariable = "Some text"; 

Quindi qual è la differenza tra ambito funzionale e ambito del blocco?

Per comprendere la differenza tra ambito funzionale e ambito del blocco, prendere in considerazione il seguente codice:

 // i IS NOT known here // j IS NOT known here // k IS known here, but undefined // l IS NOT known here function loop(arr) { // i IS known here, but undefined // j IS NOT known here // k IS known here, but has a value only the second time loop is called // l IS NOT known here for( var i = 0; i < arr.length; i++ ) { // i IS known here, and has a value // j IS NOT known here // k IS known here, but has a value only the second time loop is called // l IS NOT known here }; // i IS known here, and has a value // j IS NOT known here // k IS known here, but has a value only the second time loop is called // l IS NOT known here for( let j = 0; j < arr.length; j++ ) { // i IS known here, and has a value // j IS known here, and has a value // k IS known here, but has a value only the second time loop is called // l IS NOT known here }; // i IS known here, and has a value // j IS NOT known here // k IS known here, but has a value only the second time loop is called // l IS NOT known here } loop([1,2,3,4]); for( var k = 0; k < arr.length; k++ ) { // i IS NOT known here // j IS NOT known here // k IS known here, and has a value // l IS NOT known here }; for( let l = 0; l < arr.length; l++ ) { // i IS NOT known here // j IS NOT known here // k IS known here, and has a value // l IS known here, and has a value }; loop([1,2,3,4]); // i IS NOT known here // j IS NOT known here // k IS known here, and has a value // l IS NOT known here 

Qui, possiamo vedere che la nostra variabile j è nota solo nel primo ciclo for, ma non prima e dopo. Tuttavia, la nostra variabile i è nota nell'intera funzione.

Inoltre, considera che le variabili con scope a blocchi non sono note prima di essere dichiarate perché non vengono issate. Inoltre, non è consentito ridichiarare la stessa variabile nell'ambito dello stesso blocco. Questo rende le variabili con scope limitato meno soggette a errori rispetto a variabili globalmente o funzionalmente con scope, che vengono issate e che non producono errori nel caso di più dichiarazioni.


È sicuro utilizzare le variabili degli scope di blocco oggi?

Indipendentemente dal fatto che sia sicuro o meno oggi, dipende dal tuo ambiente:

  • Se stai scrivendo codice JavaScript lato server ( Node.js ), puoi tranquillamente usare l'istruzione let .

  • Se stai scrivendo codice JavaScript sul lato client e usi un transpiler (come Traceur ), puoi tranquillamente usare l'istruzione let , tuttavia il tuo codice è probabilmente tutt'altro che ottimale per quanto riguarda le prestazioni.

  • Se stai scrivendo codice JavaScript lato client e non usi un transpiler, devi considerare il supporto del browser.

    Oggi, 23 febbraio 2016, questi sono alcuni browser che non supportano o hanno solo supporto parziale:

    • Internet Explorer 10 e seguenti (nessun supporto)
    • Firefox 43 e versioni precedenti (nessun supporto)
    • Safari 9 e versioni precedenti (nessun supporto)
    • Opera Mini 8 e versioni precedenti (nessun supporto)
    • Browser Android 4 e seguenti (nessun supporto)
    • Opera 36 e versioni precedenti (supporto parziale)
    • Chome 51 e seguenti (supporto parziale)

inserisci la descrizione dell'immagine qui


Come tenere traccia del supporto del browser

Per una panoramica aggiornata di quali browser supportano l'istruzione let al momento della lettura di questa risposta, vedere questa pagina Can I Use .


(*) Le variabili a livello globale e funzionale possono essere inizializzate e utilizzate prima che vengano dichiarate perché le variabili JavaScript sono state issate . Ciò significa che le dichiarazioni sono sempre molto al top dello scopo.

(**) Le variabili con scope bloccate non vengono issate

Ecco un esempio:

  

Dovrai indagare sulle chiusure e su come usarle per creare membri privati .

La chiave, a quanto ho capito, è che Javascript ha lo scopeing a livello di funzione rispetto allo scoping di blocchi C più comune.

Ecco un buon articolo sull’argomento.

In “Javascript 1.7” (estensione di Mozilla in Javascript) si possono anche dichiarare variabili di scope con dichiarazione let :

  var a = 4; let (a = 3) { alert(a); // 3 } alert(a); // 4 

L’idea di scoping in JavaScript quando originariamente progettata da Brendan Eich proveniva dal linguaggio HyperTalk di scripting HyperCard .

In questa lingua, i display erano fatti come una pila di carte indice. C’era una carta principale indicata come sfondo. Era trasparente e può essere visto come la carta in basso. Qualsiasi contenuto su questa carta base è stato condiviso con le carte posizionate sopra di esso. Ogni carta posta in cima aveva il suo contenuto che aveva la precedenza sulla carta precedente, ma aveva ancora accesso alle carte precedenti se lo si desiderava.

Questo è esattamente il modo in cui è progettato il sistema di scoping di JavaScript. Ha solo nomi diversi. Le carte in JavaScript sono conosciute come contesti di esecuzione ECMA . Ciascuno di questi contesti contiene tre parti principali. Un ambiente variabile, un ambiente lessicale e un tale legame. Tornando al riferimento delle carte, l’ambiente lessicale contiene tutto il contenuto delle carte precedenti più in basso nella pila. Il contesto attuale è in cima allo stack e qualsiasi contenuto dichiarato verrà memorizzato nell’ambiente variabile. L’ambiente variabile avrà la precedenza in caso di conflitti di denominazione.

Questo legame punterà all’object contenitore. A volte gli ambiti oi contesti di esecuzione cambiano senza che l’object contenitore si modifichi, ad esempio in una funzione dichiarata in cui l’object contenitore può essere una window o una funzione di costruzione.

Questi contesti di esecuzione vengono creati ogni volta che viene trasferito il controllo. Il controllo viene trasferito quando il codice inizia ad essere eseguito, e questo viene fatto principalmente dall’esecuzione della funzione.

Quindi questa è la spiegazione tecnica. In pratica, è importante ricordare che in JavaScript

  • Gli ambiti sono tecnicamente “Contesti di esecuzione”
  • I contesti formano una pila di ambienti in cui sono memorizzate le variabili
  • La cima della pila ha la precedenza (il fondo è il contesto globale)
  • Ogni funzione crea un contesto di esecuzione (ma non sempre una nuova questa associazione)

Applicando questo a uno degli esempi precedenti (5. “Chiusura”) in questa pagina, è ansible seguire la pila di contesti di esecuzione. In questo esempio ci sono tre contesti nello stack. Sono definiti dal contesto esterno, dal contesto nella funzione invocata immediatamente chiamata da var sei e dal contesto nella funzione restituita all’interno della funzione immediatamente invocata di var sei.

i ) Il contesto esterno. Ha un ambiente variabile di a = 1
ii ) Il contesto IIFE, ha un ambiente lessicale di a = 1, ma un ambiente variabile di a = 6 che ha la precedenza nello stack
iii ) Il contesto della funzione restituita, ha un ambiente lessicale di a = 6 e questo è il valore referenziato nell’avviso quando chiamato.

inserisci la descrizione dell'immagine qui

1) Esiste un ambito globale, un ambito di funzione e gli ambiti with e catch. Non esiste un ambito di livello “blocco” in generale per le variabili – le istruzioni with e the catch aggiungono nomi ai loro blocchi.

2) Gli ambiti sono nidificati dalle funzioni fino all’ambito globale.

3) Le proprietà vengono risolte passando attraverso la catena del prototipo. L’istruzione with porta i nomi delle proprietà degli oggetti nell’ambito lessicale definito dal blocco with.

EDIT: ECMAAScript 6 (Harmony) è stato progettato per supportare let, e so che chrome permette un flag “harmony”, quindi forse lo supporta ..

Lasciate sarebbe un supporto per l’ambito a livello di blocco, ma è necessario utilizzare la parola chiave per farlo accadere.

EDIT: Sulla base del fatto che Benjamin ha sottolineato le dichiarazioni with e catch nei commenti, ho modificato il post e aggiunto altro. Sia le istruzioni with che the catch introducono le variabili nei rispettivi blocchi, e questo è un ambito di blocco. Queste variabili sono alterate alle proprietà degli oggetti passati in esse.

  //chrome (v8) var a = { 'test1':'test1val' } test1 // error not defined with (a) { var test1 = 'replaced' } test1 // undefined a // a.test1 = 'replaced' 

MODIFICA: Esempio di chiarimento:

test1 ha un ambito con il blocco with, ma è aliasato a a.test1. ‘Var test1’ crea una nuova variabile test1 nel contesto lessicale superiore (funzione o globale), a meno che non sia una proprietà di a – quale essa sia.

Yikes! Stai attento a usare ‘with’ – proprio come var è un noop se la variabile è già definita nella funzione, è anche un noop rispetto ai nomi importati dall’object! Un po ‘di testa a testa sul nome già definito lo renderebbe molto più sicuro. Io personalmente non userò mai a causa di questo.

Ho scoperto che molte persone nuove in JavaScript hanno difficoltà a capire che l’ereditarietà è disponibile per impostazione predefinita nella lingua e che l’ambito della funzione è l’unico ambito, finora. Ho fornito un’estensione a un beautifier che ho scritto alla fine dell’anno scorso chiamato JSPretty. I colors delle funzioni funzionano nell’ambito del codice e associano sempre un colore a tutte le variabili dichiarate in tale ambito. La chiusura è visivamente dimostrata quando una variabile con un colore di un ambito viene utilizzata in un ambito diverso.

Prova la funzione a:

Guarda una demo a:

Visualizza il codice in:

Attualmente la funzione offre il supporto per una profondità di 16 funzioni annidate, ma attualmente non colora le variabili globali.

JavaScript ha solo due tipi di ambito:

  1. Global Scope : Global non è altro che un ambito a livello di finestra. Qui, variabile presente in tutta l’applicazione.
  2. Ambito funzionale : la variabile dichiarata all’interno di una funzione con la parola chiave var ha un ambito funzionale.

Ogni volta che viene chiamata una funzione, viene creato un object con scope variabile (incluso nella catena di portata) che è seguito dalle variabili in JavaScript.

  a = "global"; function outer(){ b = "local"; console.log(a+b); //"globallocal" } outer(); 

Catena di portata ->

  1. Livello finestra: a e a funzione outer sono al livello più alto nella catena di portata.
  2. quando la funzione esterna ha chiamato un nuovo variable scope object (e incluso nella catena di scope) aggiunto con la variabile b al suo interno.

Ora, quando una variabile a richiede, cerca dapprima l’ambito della variabile più vicino e se la variabile non è presente rispetto a quella del prossimo object della variabile scope chain. Che è in questo caso il livello della finestra.

Solo per aggiungere alle altre risposte, scope è un elenco di ricerca di tutti gli identificatori dichiarati (variabili) e applica un rigido insieme di regole sul modo in cui questi sono accessibili al codice attualmente in esecuzione. Questa ricerca può essere allo scopo di assegnare alla variabile, che è un riferimento LHS (lefthand-side), o può essere ai fini del recupero del suo valore, che è un riferimento RHS (lato destro). Queste ricerche sono ciò che il motore JavaScript sta facendo internamente durante la compilazione e l’esecuzione del codice.

Quindi, da questo punto di vista, penso che una foto mi sarebbe stata di aiuto nell’ebook di Scopes and Closures di Kyle Simpson:

Immagine

Citando dal suo ebook:

L’edificio rappresenta il set di regole dell’ambito nidificato del nostro programma. Il primo piano dell’edificio rappresenta il tuo ambito di esecuzione corrente, ovunque tu sia. Il livello più alto dell’edificio è lo scopo globale. Risolvi i riferimenti LHS e RHS osservando il tuo piano attuale, e se non lo trovi, prendi l’ascensore per il piano successivo, guarda lì, poi il prossimo e così via. Una volta arrivato all’ultimo piano (l’ambito globale), puoi trovare ciò che stai cercando, oppure no. Ma devi fermarti a prescindere.

Una cosa che vale la pena ricordare è che “la ricerca Scope si arresta una volta trovata la prima corrispondenza”.

Questa idea di “livelli di ambito” spiega perché “questo” può essere modificato con un ambito appena creato, se viene rilevato in una funzione annidata. Ecco un link che va in tutti questi dettagli, tutto quello che volevi sapere su scope javascript

eseguire il codice. spero che questo ti dia un’idea di scoping

 Name = 'global data'; document.Name = 'current document data'; (function(window,document){ var Name = 'local data'; var myObj = { Name: 'object data', f: function(){ alert(this.Name); } }; myObj.newFun = function(){ alert(this.Name); } function testFun(){ alert("Window Scope : " + window.Name + "\nLocal Scope : " + Name + "\nObject Scope : " + this.Name + "\nCurrent document Scope : " + document.Name ); } testFun.call(myObj); })(window,document); 

Ambito globale:

Le variabili globali sono esattamente come le stelle globali (Jackie Chan, Nelson Mandela). Puoi accedervi (ottenere o impostare il valore), da qualsiasi parte della tua applicazione. Le funzioni globali sono come eventi globali (Capodanno, Natale). Puoi eseguirli (chiamarli) da qualsiasi parte della tua applicazione.

 //global variable var a = 2; //global function function b(){ console.log(a); //access global variable } 

Ambito locale:

Se sei negli Stati Uniti, potresti conoscere Kim Kardashian, famigerata celebrità (in qualche modo riesce a fare i tabloid). Ma le persone al di fuori degli Stati Uniti non la riconosceranno. È una star locale, legata al suo territorio.

Le variabili locali sono come stelle locali. È ansible solo accedervi (ottenere o impostare il valore) all’interno dell’ambito. Una funzione locale è come eventi locali: è ansible eseguire solo (festeggiare) all’interno di tale ambito. Se si desidera accedervi dall’esterno dell’ambito, verrà visualizzato un errore di riferimento

 function b(){ var d = 21; //local variable console.log(d); function dog(){ console.log(a); } dog(); //execute local function } console.log(d); //ReferenceError: dddddd is not defined 

Controlla questo articolo per una comprensione approfondita dell’ambito

Esistono ALMOST solo due tipi di ambiti JavaScript:

  • l’ambito di ciascuna dichiarazione var è associato alla funzione di chiusura più immediata
  • se non esiste alcuna funzione di inclusione per una dichiarazione var, è un ambito globale

Quindi, qualsiasi blocco diverso dalle funzioni non crea un nuovo ambito. Questo spiega perché i cicli for-over sovrascrivono le variabili con ambito esterno:

 var i = 10, v = 10; for (var i = 0; i < 5; i++) { var v = 5; } console.log(i, v); // output 5 5 

Usando invece le funzioni:

 var i = 10, v = 10; $.each([0, 1, 2, 3, 4], function(i) { var v = 5; }); console.log(i,v); // output 10 10 

Nel primo esempio, non vi era alcun ambito di blocco, quindi le variabili inizialmente dichiarate sono state sovrascritte. Nel secondo esempio, c'era un nuovo ambito a causa della funzione, quindi le variabili inizialmente dichiarate erano SHADOWED e non sovrascritte.

Questo è quasi tutto ciò che devi sapere in termini di scope JavaScript, eccetto:

In questo modo è ansible vedere lo scope JavaScript in realtà estremamente semplice, sebbene non sempre intuitivo. Alcune cose da sapere:

  • le dichiarazioni var sono issate nella parte superiore dello scope. Ciò significa che, indipendentemente da dove avviene la dichiarazione var, il compilatore è come se la variabile venisse eseguita in alto
  • vengono combinate più dichiarazioni var all'interno dello stesso ambito

Quindi questo codice:

 var i = 1; function abc() { i = 2; var i = 3; } console.log(i); // outputs 1 

è equivalente a:

 var i = 1; function abc() { var i; // var declaration moved to the top of the scope i = 2; i = 3; // the assignment stays where it is } console.log(i); 

Questo può sembrare contro intuitivo, ma ha senso dal punto di vista di un designer di linguaggio imperativo.

Modern Js, ES6 +, ‘ const ‘ e ‘ let

Dovresti utilizzare lo scope scope per ogni variabile che crei, proprio come la maggior parte delle altre lingue principali. var è obsoleto . Questo rende il tuo codice più sicuro e più manutenibile.

const dovrebbe essere usato per il 95% dei casi . Rende così il riferimento variabile non può cambiare. Le proprietà del nodo Array, object e DOM possono cambiare e dovrebbero essere const .

dovrebbe essere usato per qualsiasi variabile che si aspetta di essere riassegnata. Questo include all’interno di un ciclo for. Se cambi mai il valore oltre l’inizializzazione, usa let .

L’ambito del blocco significa che la variabile sarà disponibile solo tra parentesi in cui è dichiarata. Questo si estende agli ambiti interni, incluse le funzioni anonime create nell’ambito del tuo ambito.

Ci sono solo ambiti di funzione in JS. Non bloccare gli ambiti! Puoi vedere anche cosa sta sollevando.

 var global_variable = "global_variable"; var hoisting_variable = "global_hoist"; // Global variables printed console.log("global_scope: - global_variable: " + global_variable); console.log("global_scope: - hoisting_variable: " + hoisting_variable); if (true) { // The variable block will be global, on true condition. var block = "block"; } console.log("global_scope: - block: " + block); function local_function() { var local_variable = "local_variable"; console.log("local_scope: - local_variable: " + local_variable); console.log("local_scope: - global_variable: " + global_variable); console.log("local_scope: - block: " + block); // The hoisting_variable is undefined at the moment. console.log("local_scope: - hoisting_variable: " + hoisting_variable); var hoisting_variable = "local_hoist"; // The hoisting_variable is now set as a local one. console.log("local_scope: - hoisting_variable: " + hoisting_variable); } local_function(); // No variable in a separate function is visible into the global scope. console.log("global_scope: - local_variable: " + local_variable); 

Ogni frammento di codice JavaScript (codice o funzioni globali) ha una catena di portata ad esso associata. Questa catena dell’ambito è una lista o una catena di oggetti che definisce le variabili “nell’ambito” per quel codice. Quando JavaScript deve cercare il valore di una variabile x (un processo chiamato risoluzione variabile ), inizia guardando il primo object della catena. Se quell’object ha una proprietà denominata x , viene utilizzato il valore di tale proprietà. Se il primo object non ha una proprietà chiamata x , JavaScript continua la ricerca con l’object successivo nella catena. Se il secondo object non ha una proprietà chiamata x , la ricerca passa all’object successivo e così via. Se x non è una proprietà di nessuno degli oggetti nella catena dell’ambito, allora x non rientra nell’ambito per quel codice e si verifica un’eccezione ReferenceError. Nel codice JavaScript di primo livello (ovvero, il codice non è contenuto in alcuna definizione di funzione), la catena dell’ambito è costituita da un singolo object, l’object globale. In una funzione non annidata, la catena dell’ambito è costituita da due oggetti. Il primo è l’object che definisce i parametri della funzione e le variabili locali, mentre il secondo è l’object globale. In una funzione nidificata, la catena di ambito ha tre o più oggetti. È importante capire come viene creata questa catena di oggetti. Quando una funzione è DEFINED , memorizza la catena di ambito allora in vigore. Quando questa funzione è INVOKED , crea un nuovo object per memorizzare le sue variabili locali e aggiunge quel nuovo object alla catena dell’ambito memorizzata per creare una nuova catena più lunga che rappresenta l’ambito per tale chiamata di funzione. Questo diventa più interessante per le funzioni annidate perché ogni volta che viene chiamata la funzione esterna, la funzione interna viene nuovamente definita. Since the scope chain differs on each invocation of the outer function, the inner function will be subtly different each time it is defined—the code of the inner function will be identical on each invocation of the outer function, but the scope chain associated with that code will be different . This notion of a scope chain is crucial for understanding closures .

Try this curious example. In the example below if a were a numeric initialized at 0, you’d see 0 and then 1. Except a is an object and javascript will pass f1 a pointer of a rather than a copy of it. The result is that you get the same alert both times.

 var a = new Date(); function f1(b) { b.setDate(b.getDate()+1); alert(b.getDate()); } f1(a); alert(a.getDate()); 

My understanding is that there are 3 scopes: global scope, available globally; local scope, available to an entire function regardless of blocks; and block scope, only available to the block, statement, or expression on which it was used. Global and local scope are indicated with the keyword ‘var’, either within a function or outside, and block scope is indicated with the keyword ‘let’.

For those that believe there is only global and local scope, please explain why Mozilla would have an entire page describing the nuances of block scope in JS.

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/let

In JavaScript there are two types of scope:

  • Local scope
  • Global scope

The Below function has a local scope variable carName . And this variable is not accessible from outside of the function.

 function myFunction() { var carName = "Volvo"; alert(carName); // code here can use carName } 

The Below Class has a Global scope variable carName . And this variable is accessible from everywhere in the class.

 class { var carName = " Volvo"; // code here can use carName function myFunction() { alert(carName); // code here can use carName } } 

In EcmaScript5, there are mainly two scopes, local scope and global scope but in EcmaScript6 we have mainly three scopes, local scope, global scope and a new scope called block scope .

Example of block scope is :-

 for ( let i = 0; i < 10; i++) { statement1... statement2...// inside this scope we can access the value of i, if we want to access the value of i outside for loop it will give undefined. } 

ECMAScript 6 introduced the let and const keywords. These keywords can be used in place of the var keyword. Contrary to the var keyword, the let and const keywords support the declaration of local scope inside block statements.

 var x = 10 let y = 10 const z = 10 { x = 20 let y = 20 const z = 20 { x = 30 // x is in the global scope because of the 'var' keyword let y = 30 // y is in the local scope because of the 'let' keyword const z = 30 // z is in the local scope because of the 'const' keyword console.log(x) // 30 console.log(y) // 30 console.log(z) // 30 } console.log(x) // 30 console.log(y) // 20 console.log(z) // 20 } console.log(x) // 30 console.log(y) // 10 console.log(z) // 10 

There are two types of scopes in JavaScript.

  1. Global scope : variable which is announced in global scope can be used anywhere in the program very smoothly. Per esempio:

     var carName = " BMW"; // code here can use carName function myFunction() { // code here can use carName } 
  2. Functional scope or Local scope : variable declared in this scope can be used in its own function only. Per esempio:

     // code here can not use carName function myFunction() { var carName = "BMW"; // code here can use carName } 

Global: variable declared outside of a function

Local: variable declared inside a function, and can only be called in that scope