Scope e sollevamento della funzione Javascript


91

Ho appena letto un ottimo articolo su JavaScript Scoping and Hoisting di Ben Cherry in cui fornisce il seguente esempio:

var a = 1;

function b() {
    a = 10;
    return;

    function a() {}
}
b();
alert(a);

Utilizzando il codice sopra, il browser avviserà "1".

Non sono ancora sicuro del motivo per cui restituisce "1". Mi vengono in mente alcune delle cose che dice: tutte le dichiarazioni di funzione vengono sollevate in alto. È possibile definire l'ambito di una variabile utilizzando function. Ancora non fa clic per me.

Risposte:


122

Il sollevamento delle funzioni significa che le funzioni vengono spostate all'inizio del loro ambito. Questo è,

function b() {  
   a = 10;  
   return;  
   function a() {} 
} 

sarà riscritto dall'interprete a questo

function b() {
  function a() {}
  a = 10;
  return;
}

Strano, eh?

Inoltre, in questo caso,

function a() {}

si è comportato come

var a = function () {};

Quindi, in sostanza, questo è ciò che sta facendo il codice:

var a = 1;                 //defines "a" in global scope
function b() {  
   var a = function () {}; //defines "a" in local scope 
   a = 10;                 //overwrites local variable "a"
   return;      
}       
b();       
alert(a);                 //alerts global variable "a"

2
Quindi tutte le dichiarazioni di funzione vengono infine assegnate a una variabile?
dev.e.loper

15
@ dev.e.loper Sì, in Javascript, le funzioni sono oggetti di prima classe, proprio come stringhe e numeri. Ciò significa che sono definiti come variabili e possono essere passati ad altre funzioni, essere archiviati in array e così via.
Peter Olson

4
In nessun modo il corpo della funzione viene "riscritto". I vari standard ECMAScript affermano chiaramente che le dichiarazioni di variabili e funzioni vengono elaborate prima dell'inizio dell'esecuzione del codice. Cioè, nulla viene spostato , si tratta di ordine di esecuzione (da qui la mia antipatia per il termine "sollevamento", che deduce movimento o riorganizzazione). Nel codice riscritto, la dichiarazione var adovrebbe essere prima della dichiarazione della funzione e l'assegnazione a = 1dovrebbe essere dopo. Ma nota che questo non è specificato per accadere effettivamente dal parser, tokeniser, interprete, compilatore, qualunque cosa, è solo un equivalente.
RobG

3
@ RobG Certo, immagino che potresti chiamare la descrizione una piccola "bugia ai bambini" , ma alla fine il comportamento è lo stesso, sia che il codice sia letteralmente riorganizzato o che solo l'ordine di esecuzione sia riorganizzato. Ciò che accade effettivamente dietro le quinte è più una preoccupazione accademica e potrebbe persino dipendere dall'implementazione.
Peter Olson

7
"Inoltre, in questo caso, si è function a() {}comportato come var a = function () {};"  - questo non è corretto in due modi: primo, semmai, sarebbe stato var a = function a() {};(la funzione in realtà non è anonima), secondo, queste due forme non sono intercambiabili, perché da var a = function a() {};solo la var a;parte sarebbe stata sollevata. La a = function a() {};parte sarebbe stata ancora dietro la dichiarazione di ritorno. Poiché la forma originale è una dichiarazione di funzione e non un'espressione di funzione, viene effettivamente sollevata nel suo insieme.
Sebastian Simon

6

Quello che devi ricordare è che analizza l'intera funzione e risolve tutte le dichiarazioni delle variabili prima di eseguirla. Così....

function a() {} 

diventa davvero

var a = function () {}

var a lo forza in uno scope locale e l'ambito della variabile è attraverso l'intera funzione, quindi la variabile globale a è ancora 1 perché hai dichiarato a in uno scope locale rendendola una funzione.


5

La funzione aè sollevata all'interno della funzione b:

var a = 1; 
function b() { 
   function a() {} 
   a = 10; 
   return;
} 
b(); 
alert(a);

che è quasi come usare var:

var a = 1; 
function b() { 
   var a = function () {};
   a = 10; 
   return;
} 
b(); 
alert(a);

La funzione è dichiarata localmente e l'impostazione aavviene solo nell'ambito locale, non nella variabile globale.


1
questa riga "var a = function () {};" rende tutto chiaro .. fondamentalmente JavaScript è un linguaggio dinamico e "function" è anche un oggetto in JavaScript.
refactoring

3
  1. la dichiarazione di funzione function a(){}viene sollevata per prima e si comporta come var a = function () {};, quindi in ambito locale aviene creata.
  2. Se hai due variabili con lo stesso nome (una in globale un'altra in locale), la variabile locale ha sempre la precedenza sulla variabile globale.
  3. Quando si imposta a=10, si imposta la variabile locale a, non quella globale.

Quindi, il valore della variabile globale rimane lo stesso e ricevi un avviso 1


1

function a() { }è un'istruzione di funzione, che crea una avariabile locale alla bfunzione.
Le variabili vengono create quando una funzione viene analizzata, indipendentemente dal fatto che l' varistruzione della funzione o venga eseguita.

a = 10 imposta questa variabile locale.


a = 10imposta effettivamente una variabile nell'ambito globale quando la funzione bviene eseguita a meno che non venga aggiunta "use strict"(in ambienti come il supporto di tale direttiva).
Sean Vieira

@Sean: No, perché l'istruzione della funzione crea un identificatore locale.
SLaks

... e .... hai ragione. Non avevo capito quella particolare conseguenza della funzione di sollevamento. Grazie!
Sean Vieira

1

Qual è l'osso della contesa in questo piccolo frammento di codice?

Caso 1:

Includere la function a(){}definizione all'interno del corpo di function bcome segue.logs value of a = 1

var a = 1;
function b() {
  a = 10;
  return;

  function a() {}
}
b();
console.log(a); // logs a = 1

Caso 2

Escludere la function a(){}definizione all'interno del corpo di function bcome segue.logs value of a = 10

var a = 1;
function b() {
  a = 10;  // overwrites the value of global 'var a'
  return;
}
b();
console.log(a); // logs a = 10

L'osservazione ti aiuterà a capire che l'istruzione console.log(a)registra i seguenti valori.

Caso 1: a = 1

Caso 2: a = 10

Posizioni

  1. var a è stato definito e dichiarato lessicalmente nell'ambito globale.
  2. a=10 Questa istruzione riassegna il valore a 10, si trova lessicalmente all'interno della funzione b.

Spiegazione di entrambi i casi

A causa di function definition with name propertya è uguale a variable a. L' variable ainterno di function body bdiventa una variabile locale. La riga precedente implica che il valore globale di a rimane intatto e il valore locale di a viene aggiornato a 10.

Quindi, ciò che intendiamo dire è che il codice seguente

var a = 1;
function b() {
  a = 10;
  return;

  function a() {}
}
b();
console.log(a); // logs a = 1

Viene interpretato dall'interprete JS come segue.

var a = 1;
function b() {
  function a() {}
  a = 10;
  return;


}
b();
console.log(a); // logs a = 1

Tuttavia, quando rimuoviamo il function a(){} definition, il value of 'a'dichiarato e definito al di fuori della funzione b, quel valore viene sovrascritto e cambia in 10 nel caso 2. Il valore viene sovrascritto perché si a=10riferisce alla dichiarazione globale e se dovesse essere dichiarato localmente dobbiamo avere scritto var a = 10;.

var a = 1;
function b() {
  var a = 10; // here var a is declared and defined locally because it uses a var keyword. 
  return;
}
b();
console.log(a); // logs a = 1

Possiamo chiarire ulteriormente il nostro dubbio cambiando name propertyin function a(){} definitionun nome diverso da'a'

var a = 1;
function b() {
  a = 10; // here var a is declared and defined locally because it uses a var keyword. 
  return;

  function foo() {}
}
b();
console.log(a); // logs a = 1

1

Il sollevamento è un concetto creato per noi per renderlo più facile da capire. Quello che effettivamente accade è che le dichiarazioni vengono fatte prima rispetto ai loro scopi e gli incarichi avverranno dopo (non contemporaneamente).

Quando le dichiarazioni avvengono, var aallora function be all'interno di tale bambito, function aviene dichiarato.

Questa funzione a ombreggerà la variabile a proveniente dall'ambito globale.

Dopo che le dichiarazioni sono state fatte, l'assegnazione dei valori inizierà, il globale ariceverà il valore 1e il a dentro function briceverà 10. quando lo fai alert(a), chiamerà l'effettiva variabile di ambito globale. Questa piccola modifica al codice lo renderà più chiaro

        var a = 1;

    function b() {
        a = 10;
        return a;

        function a() { }
    }

    alert(b());
    alert(a);

1
È curioso che così tanti esperti anche in un corso su codeschool.com si riferiscano al sollevamento che non è altro che una visione semplicistica di ciò che accade, in realtà il sollevamento non avviene affatto. Rif: 1) developer.mozilla.org/en-US/docs/Glossary/Hoisting 2) Capitolo 5 di Secrets of the JavaScript Ninja 2 / e di john resig, bear bebeault, josip maras
adnan2nd

1

Sorprendentemente, nessuna delle risposte qui menziona la rilevanza del contesto di esecuzione nella catena dell'ambito.

Il motore JavaScript racchiude il codice attualmente in esecuzione in un contesto di esecuzione. Il contesto di esecuzione di base è il contesto di esecuzione globale. Ogni volta che viene richiamata una nuova funzione, viene creato un nuovo contesto di esecuzione e inserito nello stack di esecuzione. Pensa a uno Stack Frame seduto su uno Stack di invocazione in altri linguaggi di programmazione. Ultimo ad entrare, primo ad uscire. Ora ogni contesto di esecuzione ha il proprio ambiente variabile e ambiente esterno in JavaScript.

Userò l'esempio seguente come dimostrazione.

1) Per prima cosa, entriamo nella fase di creazione del contesto di esecuzione globale. Vengono creati sia l'ambiente esterno che l'ambiente variabile dell'ambiente lessicale. L'Oggetto Globale viene impostato e posto in memoria con la variabile speciale 'this' che punta ad esso. La funzione a e il suo codice e la variabile myVar con un valore indefinito vengono posti in memoria nell'ambiente variabile globale. è importante notare che il codice della funzione a non viene eseguito. Viene semplicemente inserito in memoria con la funzione a.

2) Secondo, è la fase di esecuzione del contesto di esecuzione. myVar non è più un valore indefinito. Viene inizializzato con il valore 1, che viene memorizzato nell'ambiente variabile globale. Viene richiamata la funzione a e viene creato un nuovo contesto di esecuzione.

3) Nel Contesto di Esecuzione della funzione a, passa attraverso la Fase di Creazione ed Esecuzione del proprio Contesto di Esecuzione. Ha il proprio ambiente esterno e ambiente variabile, quindi, il proprio ambiente lessicale. La funzione be la variabile myVar sono memorizzate nel suo ambiente variabile. Questo ambiente variabile è diverso dall'ambiente variabile globale. Poiché la funzione a si trova lessicalmente (fisicamente nel codice) allo stesso livello del contesto di esecuzione globale, il suo ambiente esterno è il contesto di esecuzione globale. Pertanto, se la funzione a doveva fare riferimento a una variabile che non si trova nel suo ambiente variabile, cercherà nella catena dell'ambito e proverà a trovare la variabile nell'ambiente variabile del contesto di esecuzione globale.

4) La funzione b è invocata nella funzione a. Viene creato un nuovo contesto di esecuzione. Poiché si trova lessicalmente nella funzione a, il suo ambiente esterno è a. Quindi, quando fa riferimento a myVar, poiché myVar non è nell'Ambiente variabile della funzione b, cercherà nell'Ambiente variabile della funzione a. Lo trova lì e console.log ne stampa 2. Ma se la variabile non era nella funzione Variable Environment della funzione a, allora poiché l'ambiente esterno della funzione a è il contesto di esecuzione globale, allora la Scope Chain continuerà a cercare lì.

5) Dopo che le funzioni be a hanno terminato l'esecuzione, vengono estratte dallo stack di esecuzione. Il motore JavaScript a thread singolo continua l'esecuzione nel contesto di esecuzione globale. Invoca la funzione b. Ma non esiste una funzione b nell'ambiente variabile globale e non c'è nessun altro ambiente esterno da cercare nel contesto di esecuzione globale. Quindi un'eccezione viene sollevata dal motore JavaScript.

function a(){
  function b(){
    console.log(myVar);
  }

  var myVar = 2;
  b();
}

var myVar = 1;
a();
b();
> 2
> Uncaught ReferenceError: b is not defined

L'esempio seguente mostra la catena dell'ambito in azione. Nell'ambiente variabile del contesto di esecuzione della funzione b, non è presente myVar. Quindi cerca il suo ambiente esterno, che è la funzione a. Anche la funzione a non ha myVar nel suo ambiente variabile. Quindi il motore di ricerca funziona nell'ambiente esterno di a, che è l'ambiente esterno del contesto di esecuzione globale e myVar è definito lì. Quindi, console.log stampa 1.

function a(){
  function b(){
    console.log(myVar);
  }

  b();
}

var myVar = 1;
a();
> 1

Per quanto riguarda il contesto di esecuzione e l'ambiente lessicale ad esso associato, inclusi l'ambiente esterno e l'ambiente variabile, abilitare l'ambito delle variabili in JavaScript. Anche se si richiama la stessa funzione più volte, per ogni chiamata, creerà il proprio contesto di esecuzione. Quindi ogni contesto di esecuzione avrà la propria copia delle variabili nel proprio ambiente variabile. Non c'è condivisione di variabili.


0

Sta accadendo perché il nome della variabile è uguale al nome della funzione significa "a". Pertanto, a causa del sollevamento di Javascript, cerca di risolvere il conflitto di denominazione e restituirà a = 1.

Ero anche confuso su questo fino a quando non ho letto questo post su "JavaScript Hoisting" http://www.ufthelp.com/2014/11/JavaScript-Hoisting.html

Spero che sia d'aiuto.


0

Ecco il mio riepilogo della risposta con più annotazioni e un violino di accompagnamento con cui giocare.

// hoisting_example.js

// top of scope ie. global var a = 1
var a = 1;

// new scope due to js' functional (not block) level scope
function b() {
    a = 10; // if the function 'a' didn't exist in this scope, global a = 10
  return; // the return illustrates that function 'a' is hoisted to top
  function a(){}; // 'a' will be hoisted to top as var a = function(){};
}

// exec 'b' and you would expect to see a = 10 in subsequent alert
// but the interpreter acutally 'hoisted' the function 'a' within 'b' 
// and in doing so, created a new named variable 'a' 
// which is a function within b's scope
b();

// a will alert 1, see comment above
alert(a);

https://jsfiddle.net/adjavaherian/fffpxjx7/


0

ambito e chiusura e sollevamento (var / funzione)

  1. scpope: è possibile accedere alla var globale in qualsiasi luogo (l'intero ambito del file), solo alla var locale è possibile accedere dall'ambito locale (ambito di funzione / blocco)!
    Nota: se una variabile locale non utilizza le parole chiave var in una funzione, diventerà una variabile globale!
  2. chiusura: una funzione all'interno dell'altra funzione, che può accedere all'ambito locale (funzione genitore) e all'ambito globale, anche se gli altri non possono accedere alle sue variabili! a meno che tu non lo restituisca come valore di ritorno!
  3. hoisting: sposta tutte le funzioni / dichiarazioni dichiarate / non dichiarate nell'area superiore, quindi assegna il valore o null!
    Nota: sposta semplicemente la dichiarazione, non il valore!

var a = 1;                
//"a" is global scope
function b() {  
   var a = function () {}; 
   //"a" is local scope 
   var x = 12; 
   //"x" is local scope 
   a = 10;
   //global variable "a" was overwrited by the local variable "a"  
   console.log("local a =" + a);
   return console.log("local x = " + x);
}       
b();
// local a =10
// local x = 12
console.log("global a = " + a);
// global a = 1
console.log("can't access local x = \n");
// can't access local x = 
console.log(x);
// ReferenceError: x is not defined



0

Sollevamento In JavaScript significa che le dichiarazioni di variabili vengono eseguite in tutto il programma prima che venga eseguito qualsiasi codice. Pertanto dichiarare una variabile in qualsiasi punto del codice equivale a dichiararla all'inizio.


0

Tutto dipende dall'ambito della variabile "a". Lasciatemi spiegare creando ambiti come immagini.

Qui JavaScript creerà 3 ambiti.

i) Ambito globale. ii) Scopo della funzione b (). iii) Ambito della funzione a ().

inserisci qui la descrizione dell'immagine

È chiaro che quando chiami l'ambito del metodo "avviso" appartiene a Globale in quel momento, quindi sceglierà il valore della variabile "a" dall'ambito globale solo che è 1.


0

Long Post!

Ma schiarirà l'aria!

Il modo in cui funziona Java Script è che implica un processo in due fasi:

  1. Compilazione (per così dire): questo passaggio registra le variabili e le dichiarazioni di funzione e il rispettivo ambito. Non implica la valutazione dell'espressione della funzione: var a = function(){}o dell'espressione variabile (come l'assegnazione 3a xnel caso in var x =3;cui non sia altro che la valutazione della parte RHS.)

  2. Interprete: questa è la parte di esecuzione / valutazione.

Controlla l'output del codice seguente per ottenere una comprensione:

//b() can be called here!
//c() cannot be called.
console.log("a is " + a);
console.log("b is " + b);
console.log("c is " + c);
var a = 1;
console.log("Now, a is " + a);
var c = function() {};
console.log("Now c is " + c);

function b() {
  //cannot write the below line:
  //console.log(e); 
  //since e is not declared.
  e = 10; //Java script interpreter after traversing from this function scope chain to global scope, is unable to find this variable and eventually initialises it with value 10 in global scope.
  console.log("e is " + e) //  works!
  console.log("f is " + f);
  var f = 7;
  console.log("Now f is " + f);
  console.log("d is " + d);
  return;

  function d() {}
}
b();
console.log(a);

Consente di romperlo:

  1. Nella fase di compilazione, "a" sarebbe registrato nell'ambito di ambito globale con valore " undefined". Lo stesso vale per " c", il suo valore in questo momento sarebbe " undefined" e non " function()". ' b' verrebbe registrato come funzione nell'ambito globale. All'interno bdell'ambito di, " f" verrebbe registrata come una variabile che in questo momento sarebbe indefinita e la funzione " d" verrebbe registrata.

  2. Quando viene eseguito l'interprete, è function()possibile accedere alle variabili dichiarate e (e non alle espressioni) prima che l'interprete raggiunga la riga dell'espressione effettiva. Quindi, le variabili verrebbero stampate ' undefined' e la funzione anonima dichiarata può essere chiamata prima. Tuttavia, il tentativo di accedere a una variabile non dichiarata prima dell'inizializzazione dell'espressione comporterebbe un errore come:

console.log(e)
e = 3;

Ora, cosa succede quando hai una dichiarazione di variabile e funzione con lo stesso nome.

La risposta è : le funzioni vengono sempre caricate prima e se viene dichiarata la variabile con lo stesso nome, viene trattata come duplicata e ignorata. Ricorda, l'ordine non ha importanza. Le funzioni hanno sempre la precedenza. Ma durante la fase di valutazione puoi cambiare il riferimento della variabile a qualsiasi cosa (memorizza qualunque sia stata l'ultima assegnazione) Dai un'occhiata al codice seguente:

var a = 1;
console.log("a is " + a);

function b() {
  console.log("a inside the function b is " + a); //interpreter finds                                'a' as function() in current scope. No need to go outside the scope to find 'a'.
  a = 3; //a changed
  console.log("Now a is " + a);
  return;

  function a() {}
}
var a; //treated as duplicate and ignored.
b();
console.log("a is still " + a + " in global scope"); //This is global scope a.


0

Il sollevamento è un concetto comportamentale di JavaScript. Il sollevamento (diciamo lo spostamento) è un concetto che spiega come e dove le variabili devono essere dichiarate.

In JavaScript, una variabile può essere dichiarata dopo che è stata utilizzata perché le dichiarazioni di funzione e le dichiarazioni di variabile vengono sempre spostate ("sollevate") in modo invisibile all'inizio del loro ambito contenitore dall'interprete JavaScript.

Nella maggior parte dei casi incontriamo due tipi di sollevamento.

1.Dichiarazione variabile di sollevamento

Capiamo questo da questo pezzo di codice.

 a = 5; // Assign 5 to a
 elem = document.getElementById("demo"); // Find an element 
 elem.innerHTML = a;                     // Display a in the element
 var a; // Declare a
  //output-> 5

Qui la dichiarazione della variabile a sarà ospitata in alto in modo invisibile dall'interprete javascript al momento della compilazione. Quindi siamo stati in grado di ottenere il valore di a. Ma questo approccio di dichiarazione delle variabili non è raccomandato in quanto dovremmo dichiarare le variabili in cima già in questo modo.

 var a = 5; // Assign and declare 5 to a
 elem = document.getElementById("demo"); // Find an element 
 elem.innerHTML = a;                     // Display a in the element
  // output -> 5

considera un altro esempio.

  function foo() {
     console.log(x)
     var x = 1;
 }

è effettivamente interpretato in questo modo:

  function foo() {
     var x;
     console.log(x)
     x = 1;
  }

In questo caso x sarà indefinito

Non importa se è stato eseguito il codice che contiene la dichiarazione di variabile. Considera questo esempio.

  function foo() {
     if (false) {
         var a = 1;
     }
     return;
     var b = 1;
  }

Questa funzione risulta essere così.

  function foo() {
      var a, b;
      if (false) {
        a = 1;
     }
     return;
     b = 1;
  }

Nella dichiarazione di variabile vengono montati solo gli argani a definizione di variabile, non l'assegnazione.

  1. Dichiarazione di funzione sollevamento

A differenza della variabile sollevamento, verrà sollevato anche il corpo della funzione o il valore assegnato. Considera questo codice

 function demo() {
     foo(); // this will give error because it is variable hoisting
     bar(); // "this will run!" as it is function hoisting
     var foo = function () {
         alert("this would not run!!");
     }
     function bar() { 
         alert("this will run!!");
     }
 }
 demo();

Ora che abbiamo capito sia il sollevamento delle variabili che quello delle funzioni, capiamo ora questo codice.

var a = 1;
function b() {
  a = 10;
  return;
   function a() {}
}
b();
alert(a);

Questo codice risulterà essere così.

var a = 1;                 //defines "a" in global scope
 function b() {  
   var a = function () {}; //defines "a" in local scope 
    a = 10;                 //overwrites local variable "a"
    return;      
 }       
 b();       
 alert(a); 

La funzione a () avrà un ambito locale all'interno di b (). a () verrà spostato all'inizio durante l'interpretazione del codice con la sua definizione (solo in caso di sollevamento della funzione) quindi a now avrà un ambito locale e quindi non influenzerà l'ambito globale di un pur avendo il proprio ambito all'interno della funzione b () .


0

Dalla mia conoscenza, il sollevamento avviene con la dichiarazione di variabile e la dichiarazione di funzione, ad esempio:

a = 7;
var a;
console.log(a) 

Cosa succede all'interno del motore di JavaScript:

var a;
a = 7;
console.log(a);
// 7

O:

console.log(square(7)); // Output: 49
function square(n) { return n * n; }

Diventerà:

function square(n) { return n * n; }
console.log(square(7)); // 49

Tuttavia, le assegnazioni come l'assegnazione di variabili e l'assegnazione di espressioni di funzione non verranno sollevate: Ad esempio:

console.log(x);
var x = 7; // undefined

Potrebbe diventare così:

var x;
console.log(x); // undefined
x = 7;

0

Descrivere l'hosting in javascript in una frase significa che le variabili e le funzioni sono innalzate in cima all'ambito in cui sono dichiarate.

inserisci qui la descrizione dell'immagine

Presumo che tu sia un principiante, per capire correttamente il sollevamento all'inizio abbiamo capito la differenza tra undefined e ReferenceError

 var v;
 console.log(v);
 console.log(abc);
/*
The output of the above codes are:
undefined
ReferenceError: abc is not defined*/

ora nel codice qui sotto cosa vediamo? una variabile e un'espressione di funzione è decleard.

<script>
var totalAmo = 8;
var getSum = function(a, b){
      return a+b;
}
</script>

ma l'immagine reale con la prova che sia la variabile che la funzione sono sollevate in cima a questo ambito:

console.log(totalAmo);
console.log(getSum(8,9));
var totalAmo = 8;
var getSum = function(a, b){
      return a+b;
}
console.log(totalAmo);
console.log(getSum(9,7));

L'output dei primi due log non è definito e TypeError: getSum non è una funzione perché sia ​​var totalAmo che getSum sono posizionati in cima al loro ambito come sotto

 <script>
        var totalAmo;
        var getSum;

        console.log(totalAmo);
        console.log(getSum(8,9));
        var totalAmo = 8;
        var getSum = function(a, b){
            return a+b;
        }
        console.log(totalAmo);
        console.log(getSum(9,7));
    </script>

Ma per la dichiarazione di funzioni, intere funzioni vengono poste in cima al loro ambito.

console.log(getId());
function getId(){
   return 739373;
}
/* output: 739373, because the whole function hoisted on the top of the scope.*/

Ora la stessa logica vale per quelle varibale, le esperienze di funzioni e le dichiarazioni di funzione dichiarate all'interno dell'ambito funzionale. Punto chiave: non verranno issati in cima alla lima ;

function functionScope(){
            var totalAmo;
            var getSum;

            console.log(totalAmo);
            console.log(getSum(8,9));
            var totalAmo = 8;
            var getSum = function(a, b){
                return a+b;
            }
        }

Quindi, quando usi la parola chiave var , la variabile e la funzione posizionati in cima allo scope (ambito globale e ambito della funzione). Che dire di let e const , const e let sono ancora entrambi consapevoli dell'ambito globale e dell'ambito della funzione proprio come lo è var, ma le variabili const e let sono anche consapevoli di un altro ambito chiamato ambito bloccato. uno scope di blocco è presente ogni volta che c'è un blocco di codice, come for loop, if else, while loop ecc.

Quando usiamo const e let per dichiarare una variabile in questo ambito di blocco, la dichiarazione della variabile verrà posizionata solo in cima a quel blocco in cui si trova, e non sarà in cima alla funzione genitore o in cima al portata globale che viene sollevata.

 function getTotal(){
            let total=0;
            for(var i = 0; i<10; i++){
                let valueToAdd = i;
                var multiplier = 2;
                total += valueToAdd*multiplier;
            }
            return total;
        }

Le variabili nell'esempio di Adobe verranno sollevate come sotto

 function getTotal(){
            let total;
            var multiplier;
            total = 0;
            for(var i = 0; i<10; i++){
                let valueToAdd;
                valueToAdd = i;
                multiplier = 2;
                total += valueToAdd*multiplier;
            }
            return total;
        }

0

ES5: sollevamento funzione e sollevamento variabile

function hoistingla priorità è greaterdivariable hoisting

"use strict";

/**
 *
 * @author xgqfrms
 * @license MIT
 * @copyright xgqfrms
 * @created 2016-06-01
 * @modified
 *
 * @description function-hoisting.js
 * @augments
 * @example
 * @link
 *
 */

(function() {
  const log = console.log;

  var a = 1;
  function b() {
    a = 10;
    log(`local a`, a)
    return;
    // function hoisting priority is greater than variable hoisting
    function a() {}
  }
  b();
  log(`global a`, a);
  // local a 10
  // global a 1
})();



che è uguale a

(function() {
  const log = console.log;

  // define "a" in global scope
  var a = 1;
  function b() {
    // define "a" in local scope
    var a ;
    // assign function to a
    a = function () {};
    // overwrites local variable "a"
    a = 10;
    log(`local a`, a);
    return;
  }

  b();
  // log global variable "a"
  log(`global a`, a);

  // local a 10
  // global a 1
})();

il motivo dietro il sollevamento

var a = 1;                
//"a" is global scope
function b() {  
   var a = function () {}; 
   //"a" is local scope 
   var x = 12; 
   //"x" is local scope 
   a = 10;
   //global variable "a" was overwrited by the local variable "a"  
   console.log("local a =" + a);
   return console.log("local x = " + x);
}       
b();
// local a =10
// local x = 12
console.log("global a = " + a);
// global a = 1
console.log("can't access local x = \n");
// can't access local x = 
console.log(x);
// ReferenceError: x is not defined

/**
 *  scpope & closure & hoisting (var/function)
 *  
 * 1. scpope : the global var can be access in any place(the whole file scope), local var only can be accessed by the local scope(function/block scope)!
 * Note: if a local variable not using var keywords in a function, it will become a global variable!
 * 
 * 2. closure : a function inner the other function, which can access local scope(parent function) & global scope, howerver it's vars can't be accessed by others! unless, your return it as return value!
 * 
 * 3. hoisting : move all declare/undeclare vars/function to the scope top, than assign the value or null!
 * Note: it just move the declare, not move the value!
 * 
 */

ES6 let, constnon esiste sollevamento

(() => {
  const log = console.log;
  log(a)
  // Error: Uncaught ReferenceError: Cannot access 'a' before initialization
  let a = 1;
})();



(() => {
  const log = console.log;
  log(b)
  // Error: Uncaught ReferenceError: Cannot access 'b' before initialization
  const b = 1;
})();

rif

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

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

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

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.