Domeniul de aplicare definește durata de viață și vizibilitatea unei variabile. Variabilele nu sunt vizibile în afara domeniului în care sunt declarate.

JavaScript are sfera modulului, sfera funcției, sfera blocului, sfera lexicală și sfera globală.

Domeniul de aplicare global

Variabilele definite în afara oricărei funcții, blocuri sau domenii ale modulului au domeniu global. Variabilele din domeniul global pot fi accesate de oriunde din aplicație.

Când un sistem de module este activat, este mai greu să faci variabile globale, dar se poate face totuși. Prin definirea unei variabile în HTML, în afara oricărei funcții, se poate crea o variabilă globală:

<script>
  let GLOBAL_DATA = { value : 1};
</script>

console.log(GLOBAL_DATA);

Atunci când nu există un sistem de module, este mult mai ușor să creați variabile globale. O variabilă declarată în afara oricărei funcții, în orice fișier, este o variabilă globală.

Variabilele globale sunt disponibile pe toată durata de viață a aplicației.

O altă modalitate de a crea o variabilă globală este utilizarea window obiect global oriunde în aplicație:

window.GLOBAL_DATA = { value: 1 };

În acest moment, GLOBAL_DATA variabila este vizibilă peste tot.

console.log(GLOBAL_DATA)

După cum vă puteți imagina, aceste practici sunt practici rele.

Domeniul de aplicare al modulului

Înainte de module, o variabilă declarată în afara oricărei funcții era o variabilă globală. În module, o variabilă declarată în afara oricărei funcții este ascunsă și nu este disponibilă pentru alte module decât dacă este exportată în mod explicit.

Exportul face o funcție sau un obiect disponibil pentru alte module. În exemplul următor, export o funcție din sequence.js fișier modul:

// in sequence.js
export { sequence, toList, take };

Importarea pune la dispoziția modulului curent o funcție sau un obiect, din alte module.

import { sequence, toList, toList } from "./sequence";

Într-un fel, ne putem imagina un modul ca o funcție de autoexecutare care ia datele de import ca intrări și returnează datele de export.

Domeniul funcției

Domeniul funcției înseamnă că parametrii și variabilele definite într-o funcție sunt vizibile oriunde în cadrul funcției, dar nu sunt vizibile în afara funcției.

Luați în considerare următoarea funcție care se execută automat, numită IIFE.

(function autoexecute() {
    let x = 1;
})();

console.log(x);
//Uncaught ReferenceError: x is not defined

IIFE înseamnă Expresia funcției invocate imediat și este o funcție care rulează imediat după definirea sa.

Variabile declarate cu var au doar sfera funcției. Mai mult, variabile declarate cu var sunt ridicate până la vârful scopului lor. În acest fel pot fi accesate înainte de a fi declarate. Aruncați o privire la codul de mai jos:

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

doSomething(); //undefined

Acest lucru nu se întâmplă pentru let. O variabilă declarată cu let poate fi accesat numai după definirea sa.

function doSomething(){
  console.log(x);
  let x = 1;
}

doSomething();
//Uncaught ReferenceError: x is not defined

O variabilă declarată cu var poate fi re-declarat de mai multe ori în același domeniu. Următorul cod este bine:

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

doSomething();

Variabile declarate cu let sau const nu poate fi re-declarat în același domeniu:

function doSomething(){
  let x = 1
  let x = 2;
}
//Uncaught SyntaxError: Identifier 'x' has already been declared

Poate că nici nu trebuie să ne pese de asta, așa cum var a început să devină depășită.

Scopul blocului

Scopul blocului este definit cu acolade. Este separat de { și }.

Variabile declarate cu let și const poate avea scop de blocare. Acestea pot fi accesate numai în blocul în care sunt definite.

Luați în considerare următorul cod care subliniază let sfera de blocare:

let x = 1;
{ 
  let x = 2;
}
console.log(x); //1

În schimb, var declarația nu are domeniul de aplicare al blocului:

var x = 1;
{ 
  var x = 2;
}
console.log(x); //2

O altă problemă obișnuită cu lipsa scopului de blocare este utilizarea unei operații asincrone ca setTimeout() într-o buclă. Codul buclei curgătoare afișează numărul de 5, de cinci ori.

(function run(){
    for(var i=0; i<5; i++){
        setTimeout(function logValue(){
            console.log(i);         //5
        }, 100);
    }
})();

for declarație buclă, cu let declarație, creează o nouă variabilă locală pentru domeniul de aplicare al blocului, pentru fiecare iterație. Următorul cod de buclă arată 0 1 2 3 4 5.

(function run(){
  for(let i=0; i<5; i++){
    setTimeout(function log(){
      console.log(i); //0 1 2 3 4
    }, 100);
  }
})();

Domeniul lexical

Sfera lexicală este capacitatea funcției interioare de a accesa sfera exterioară în care este definită.

Luați în considerare următorul cod:

(function autorun(){
    let x = 1;
    function log(){
      console.log(x);
    };
    
    function run(fn){
      let x = 100;
      fn();
    }
    
    run(log);//1
})();

log funcția este o închidere. Se referă la x variabilă de la funcția sa părinte autorun(), nu cel din run() funcţie.

Funcția de închidere are acces la domeniul în care a fost creată, nu la domeniul în care a fost executată.

Domeniul funcției locale a autorun() este domeniul lexical al log() funcţie.

Lanțul de aplicare

Fiecare domeniu are o legătură cu domeniul părinte. Atunci când este utilizată o variabilă, JavaScript privește lanțul domeniului de aplicare până când găsește variabila solicitată sau până când ajunge la domeniul global, care este sfârșitul lanțului de domeniu.

Uită-te la următorul exemplu:

let x0 = 0;
(function autorun1(){
 let x1 = 1;
  
 (function autorun2(){
   let x2 = 2;
  
   (function autorun3(){
     let x3 = 3;
      
     console.log(x0 + " " + x1 + " " + x2 + " " + x3);//0 1 2 3
    })();
  })();
})();

autorun3() funcția interioară are acces la local x3 variabil. De asemenea, are acces la x1 și x2 variabile din funcțiile externe și x0 variabila globala.

Dacă nu poate găsi variabila, va returna o eroare în modul strict.

"use strict";
x = 1;
console.log(x)
//Uncaught ReferenceError: x is not defined

În modul non-strict, denumit „mod neglijent”, va face un lucru rău și va crea o variabilă globală.

x = 1;
console.log(x); //1

Concluzie

Variabilele definite în domeniul global sunt disponibile oriunde în aplicație.

Într-un modul, o variabilă declarată în afara oricărei funcții este ascunsă și nu este disponibilă pentru alte module decât dacă este exportată în mod explicit.

Domeniul funcției înseamnă că parametrii și variabilele definite într-o funcție sunt vizibile oriunde în cadrul funcției

Variabile declarate cu let și const au scop de blocare. var nu are scop de blocare.

Descoperiți JavaScript funcțional a fost numit unul dintre cele mai bune cărți noi de programare funcțională de BookAuthority!

Pentru mai multe despre aplicarea tehnicilor de programare funcționale în React, aruncați o privire Reactie functionala.

Învăța funcțional React, într-un mod bazat pe proiecte, cu Arhitectură funcțională cu React și Redux.

Urmăriți pe Twitter