JavaScript Funzione Scoping


Esempio

Quando si definisce una funzione, viene creato un ambito .

Tutto ciò che è definito all'interno della funzione non è accessibile dal codice al di fuori della funzione. Solo il codice all'interno di questo ambito può vedere le entità definite all'interno dell'ambito.

function foo() {
  var a = 'hello';
  console.log(a);  // => 'hello'
}

console.log(a);  // reference error

Le funzioni annidate sono possibili in JavaScript e si applicano le stesse regole.

function foo() {
  var a = 'hello';
  
  function bar() {
    var b = 'world';
    console.log(a);  // => 'hello'
    console.log(b);  // => 'world'
  }

  console.log(a);  // => 'hello'
  console.log(b);  // reference error
}

console.log(a);  // reference error
console.log(b);  // reference error

Quando JavaScript tenta di risolvere un riferimento o una variabile, inizia a cercarlo nell'ambito corrente. Se non riesce a trovare quella dichiarazione nello scope corrente, si arrampica su un ambito per cercarlo. Questo processo si ripete finché non viene trovata la dichiarazione. Se il parser JavaScript raggiunge l'ambito globale e ancora non riesce a trovare il riferimento, verrà generato un errore di riferimento.

var a = 'hello';

function foo() {
  var b = 'world';

  function bar() {
    var c = '!!';

    console.log(a);  // => 'hello'
    console.log(b);  // => 'world'
    console.log(c);  // => '!!'
    console.log(d);  // reference error
  }
}

Questo comportamento di arrampicata può anche significare che un riferimento può "ombreggiare" su un riferimento con un nome simile nello scope esterno poiché viene visto per primo.

var a = 'hello';

function foo() {
  var a = 'world';

  function bar() {
    console.log(a);  // => 'world'
  }
}
6

Il modo in cui JavaScript risolve l'ambito si applica anche alla parola chiave const . Dichiarare una variabile con la parola chiave const implica che non è consentito riassegnare il valore, ma dichiararlo in una funzione creerà un nuovo ambito e con esso una nuova variabile.

function foo() {
  const a = true;

  function bar() {
    const a = false;  // different variable
    console.log(a);   // false
  }

  const a = false;    // SyntaxError
  a = false;          // TypeError
  console.log(a);     // true
}

Tuttavia, le funzioni non sono gli unici blocchi che creano un ambito (se si utilizza let o const ). let e le dichiarazioni const hanno un ambito dell'istruzione di blocco più vicina. Vedi qui per una descrizione più dettagliata.