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.
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.