O introducere în domeniul de aplicare în JavaScript

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ă:

 let GLOBAL_DATA = { value : 1};  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 creare a unei variabile globale este utilizarea windowobiectului global oriunde în aplicație:

window.GLOBAL_DATA = { value: 1 };

În acest moment, GLOBAL_DATAvariabila 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.jsfișierul modulului:

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

Variabilele declarate cu varau doar sfera funcției. Și mai mult, variabilele declarate cu varsunt ridicate în partea de sus a domeniului lor de aplicare. Î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 letpoate 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 varpoate fi declarată din nou de mai multe ori în același domeniu. Următorul cod este în regulă:

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

Variabilele declarate cu letsau constnu pot fi declarate din nou î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 acest lucru, deoarece vara început să devină depășit.

Scopul blocului

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

Variabilele declarate cu letși constpot avea sfera de blocare. Acestea pot fi accesate numai în blocul în care sunt definite.

Luați în considerare următorul cod care subliniază letdomeniul de aplicare al blocurilor:

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

În schimb, vardeclaraț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); } })();

Instrucțiunea forbuclă, împreună cu letdeclarația, 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 })();

logFuncția este o închidere. Se referă la xvariabila din funcția sa părinte autorun(), nu pe cea 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ă.

The local function scope of autorun() is the lexical scope of the log() function.

Scope chain

Every scope has a link to the parent scope. When a variable is used, JavaScript looks down the scope chain until it either finds the requested variable or until it reaches the global scope, which is the end of the scope chain.

Look at the next example:

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 })(); })(); })();

The autorun3() inner function has access to the local x3 variable. It has also access to the x1 and x2 variables from the outer functions and the x0 global variable.

If it cannot find the variable, it will return an error in strict mode.

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

In non-strict mode, referred to as “sloppy mode”, it will do a bad thing and create a global variable.

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

Conclusion

Variables defined in global scope are available everywhere in the application.

In a module, a variable declared outside any function is hidden and not available to other modules unless it is explicitly exported.

Function scope means that parameters and variables defined in a function are visible everywhere within the function

Variables declared with let and const have block scope. var doesn’t have block scope.

Discover Functional JavaScript was named one of thebest new Functional Programming books by BookAuthority!

For more on applying functional programming techniques in React take a look atFunctional React.

Learn functional React, in a project-based way, with Functional Architecture with React and Redux.

Follow on Twitter