Jag skulle försöka förklara lexical scope på vanlig engelska. Önska mig lycka till
medan du skriver en artikel om stängningar och IIFE några dagar tillbaka. Jag försökte förklara lexical scope på ett kort och enkelt sätt. Jag märkte att artikeln blev större och större så jag bestämde mig bara för att skriva om lexical scope separat.
i den här artikeln skulle jag försöka förklara grunderna i lexikala omfattning, vad det innebär och ge exempel för att hjälpa dig att förstå hur det fungerar i JavaScript. Inga slagord…Jag lovar.
För det första, låt oss bryta ner ordet ”Lexical Scope”.
scope
vi pratar om den enkla först: scope.
på vanlig engelska kan omfattning betyda:
- en gräns
- en region
- en miljö
eller någon annan synonym du kan tänka dig.
kommer du ihåg att titta på en handledning där instruktören berättar att en viss ide / ämne ligger utanför videoens omfattning?
eller när ett team från en annan avdelning arbetar med ett projekt och du berättar för dem att lägga till en funktion som du tycker är cool och de säger till dig: ”Det ligger utanför projektets omfattning”.
Jag tror att du får kontentan. Omfattning är helt enkelt en region där något får fungera under en viss tidsperiod.
i datavetenskap kan detta betyda en region där vissa data finns och kan nås. Dessa data kan vara något som en variabel.
på ett språk som JavaScript kan vi definiera ett omfång genom att skapa ett block med lockiga hängslen: {...}
. Vi kallar detta Blockomfång. Detta innebär att variabler som deklareras i detta block endast kan nås inom denna region. Denna region täcker allt inuti den, inklusive andra barn/inre block skapade inom den regionen. med andra ord är denna region local
och dess variabler kan inte nås direkt från omvärlden. Så detta kan kallas en lokal räckvidd.
variabler som deklareras inuti funktioner finns i funktionens lokala omfattning.
function doSomething() { let name = "john"; console.log(name)}doSomething(); // Prints 'john'// would produce a Reference error// because name is local to doSomething() function's scopeconsole.log(name);
Nu kanske du har hört talas om Global omfattning tidigare. Tja, det är en miljö som inte är innesluten i ett block. Varje kod i din Javascript-miljö har tillgång till den. Detta är den öppna JavaScript-miljön. Så koden nedan ska fungera.
let name = "john"; // In the global scopefunction doSomething() { name = "James" console.log(name); // The function can access the global scope variable 'name'}doSomething(); // Prints "James"console.log(name); // Can access 'name' too
en sak att notera:
ett omfång har tillgång till sitt överordnade omfång men det överordnade omfånget har inte direkt tillgång till variabler som deklarerats i ett inre omfång.
funktionen har åtkomst till name
eftersom funktionen deklareras i det globala omfånget och name
finns i det globala omfånget. Om namnet deklarerades inuti funktionen doSomething()
, kan koden i det globala omfånget inte ändra värdet påname
direkt eftersomname
är lokalt för funktionen.
Jag tror att du har en god förståelse för vad omfattning innebär. Det betyder helt enkelt en region eller miljö där en variabel finns och kan nås eller ändras.låt oss nu prata om ”Lexical”
Lexical
för att förstå lexical, låt oss först titta på ordet från vilket det härrör från: Lexicon.
lexikon härstammar från det latinska ordet: ”lexis” som betyder ”ord”
på vanlig engelska:
lexikon betyder helt enkelt en ordbok. I ordord betyder det en ordförråd av en persons språk. Det är som en bok där betydelsen/definitionen av ord lagras.
När du vill hitta betydelsen av ett ord går du till Lexikonet.
du tittar inte på var Ordet används och gissar vad det betyder och dess innehåll eller värde. Du går alltid lexikonet, där ordets syfte skapas och tydligt definieras.
nu med den förklaringen:
Lexical betyder helt enkelt något relaterat till Lexikonet. Med andra ord betyder det något relaterat till ord eller ordförråd i en persons språk. Något relaterat till skapandet eller definitionen av ord.
låt oss prata om lexiskt omfång.
Lexical Scope
Vi har sett betydelsen av de två orden på vanlig engelska.
med den kunskapen, låt oss definiera Lexical Scope på vanlig engelska:
Lexical Scope betyder helt enkelt att regionen där ett ord finns bestäms av var det definierades eller skapades.
andra definitioner skulle vara:
Lexical Scope betyder att betydelsen/värdet av ett ord endast kan bestämmas av regionen/miljön där det skapades.
Lexical Scope betyder att du inte direkt lägger ut betydelsen av ett ord till personer från en extern region som använder ordet. Detta beror på att lexical lägger tonvikten på ursprunget på var det skapades/definierades.
Okej, Jag ska ge ett exempel.
Låt oss använda ordet:”Dans”.
ordet ”dans” skapades/definierades i Storbritannien. Det brittiska folket vet dess mening. Detta ord finns i det område där det skapades:”Storbritannien”. Wales är i Storbritannien så Wales har tillgång till detta ord (kom ihåg att vi redan förklarat varför ovan). Så det walisiska folket kan uppdatera betydelsen av detta ord för att passa deras lokala dialekt. Detta beror på att de ligger inom Storbritanniens räckvidd.
tyskarna kan inte direkt komma och ändra betydelsen av detta ord. Detta beror på att ordet inte skapades i Tyskland. Så om tyskarna ville använda det engelska ordet:” dans ” och det ordet ännu inte har skapats av Storbritannien, skulle det ordet inte vara tillgängligt oavsett hur svårt de försöker. Detta skulle göra att ingen vet den faktiska betydelsen av det ordet i Tyskland eftersom ordet inte finns i det brittiska lexikonet. (Oroa dig inte om detta verkar gibberish, jag förklarar med kod senare)
eftersom vi är vetenskapsstudenter och inte lingvister, låt oss ersätta ”word” med ”variabel”.
vår nya definition skulle vara:
Lexical Scope betyder helt enkelt att regionen där en variabel finns bestäms av var den definierades eller skapades.
Lexical Scope betyder att betydelsen/värdet av en variabel endast kan bestämmas av regionen / miljön där den skapades.
Lexical Scope innebär att du inte direkt lägger ut betydelsen av en variabel för att koda från en extern region(block) som använder variabeln. Detta beror på att lexical lägger tonvikten på ursprunget på var variabeln skapades/definierades.
Så vad lexical scope visar oss är att en variabel endast kan användas i det omfång där den skapades och inte där den kallades.
Låt oss se hur detta fungerar i kod:
function rideBritishBoat() { let boatName = "Queen's Dab"; // local variable return `Driving ${boatName}`}function rideGermanBoat() { const status = rideBritishBoat(); return status;}rideGermanBoat();
exemplet ovan simulerar ett scenario där tyskarna köpte en båt från Storbritannien….(Du kan byta det som någonsin land du want…no måste kämpa varför jag inte nämnde något annat land. Det här är bara landnamn och inte JavaScript-bibliotek (t.ex.rideGermanBoat()
använder rideBritishBoat()
.
eftersom JavaScript använder lexical scope, när du kör funktionen rideBritishBoat()
, går den till var den skapades och får referensen till variabeln: boatName
. Så med lexical scoping, när rideBritishBoat()
körs, går JavaScript in i funktionens räckvidd för att leta efter variablerna som används i den här funktionen.
Obs: omfattningen av funktionen rideBritishBoat()
är dess lokala omfattning och det globala omfattningen. Funktionen rideGermanBoat()
finns inte i det lexikala omfånget för funktionen rideBritishBoat()
eftersom rideBritishBoat()
inte skapades inuti den.
låt oss nu ändra exemplet lite:
function rideBritishBoat() { return `Driving ${boatName}`; // Reference Error: boatName not defined}function rideGermanBoat() { let boatName = "Merkel's Dab"; const status = rideBritishBoat(); return status;}rideGermanBoat();
ovanstående kod misslyckas. FunktionernarideBritishBoat()
är inte exakta. Det misslyckas när du försöker komma åt boatName
I returdeklarationen.
varför?
detta beror på att JavaScript använder lexical scope.
hur detta fungerar är när det stöter påboatName
variabel inutirideBritishBoat()
funktion, det Letar efter varboatName
variabel skapades i dess omfång kedja. Det vill säga all möjlig omfattning av den funktionen som är: lokal omfattning av funktionen, då kontrollerar den dess omslutande omfattning i detta fall den globala omfattningen.
så det är hur JavaScript kontrollerar variabler. Den kontrollerar först det lokala blocket där den aktuella variabeln används för att veta om den deklarerades där. Om det inte var så går det upp till det omslutande omfånget och fortsätter om det inte hittar en deklaration tills den når toppen av kedjan som är det globala omfånget
det finns en annan typ av Scoping som kallas ”dynamisk Scoping”.
den tidigare koden skulle fungera på ett språk som stöder dynamisk scoping(t.ex.Lisp).
Detta beror på att variabeln i en dynamiskt avgränsad miljö kontrolleras vid körning. Vad betyder är att när du kör rideGermanBoat()
och exekvering kommer till rideBritishBoat()
kontrollerar runtime Environment för värdet av boatName
där koden för närvarande körs. I det här fallet finner det, så inga problem och koden fungerar vid förväntat och skriver ut Driving Merkel's Dab
.
lexiskt omfång kallas också statiskt omfång eftersom dess omfång bestäms vid kompileringstid. Det betyder att det är miljö / omfattning är fast och kan inte bara förändras. Med andra ord kan variabler endast anropas från det kodblock där det deklarerades/skapades.
dynamiskt omfång kallas dynamiskt eftersom dess miljö (yttre omfång) kan förändras. Med andra ord kan variabler anropas utanför blocket som de skapas.
Så vi kan ha en annan funktion som använder rideBritishBoat()
som heter rideMauritianBoat()
:
function rideMauritianBoat() { let boatName = "Flying Dodo's Dab"; const status = rideBritishBoat(); return status;}rideMauritianBoat();
på ett dynamiskt språk kan du se värdet påboatName
variabel inutirideBritishBoat()
är beroende av omfattningen där den körs. Som vi kan se att detta omfång kan förändras är det därför dynamiskt.
så inutirideBritishBoat()
, kallar denboatName
variabel avrideMauritianBoat()
som ligger utanför dess blockomfång.
det är dynamisk Scoping och Lexical Scoping är motsatsen.
men kom ihåg, JavaScript är inte dynamiskt scoped. Detta är bara för att visa dig skillnaden.
så lexical scoping kontrollerar för variabler vid kompileringstid (variabler måste skapas och vara tillgängliga i omfattningen/blocket som den används) medan dynamisk scoping kontrollerar för variabler vid körning (variabler kanske inte skapas i omfattningen vid kompilering men kan vara närvarande när funktionen körs).
Senior Devs vara som: Dude!! JavaScript är inte ett kompilerat språk!!
snälla, låt oss lämna det samtalet för en annan dag. Försök bara få meddelandet jag passerar.
Okej, Jag är förbannad just nu. Här är en övning för dig.
snabb träning
vad skulle vara resultatet av denna funktion?
function rideBritishBoat() { let boatName = "Queen's Dab"; function rideWelshBoat() { boatName = "Welsh Royal Boat"; console.log(boatName) } rideWelshBoat();}rideBritishBoat()
sammanfattning
syftet med denna artikel var att förklara lexikal scoping på ett enkelt sätt med hjälp av grundläggande grammatik och korta exempel. Om du märkte några ord är i fetstil. Det är nyckelorden för att förstå detta koncept. Dessutom har jag många alternativa definitioner av samma begrepp. Detta gjordes för dig att välja vilken som sjunker in lätt för dig. Olika slag för olika människor som vi har lärt oss ovan kan vi säga att:
- ett omfång är en miljö / region där något (en variabel) existerar
- ett omfång kan komma åt sina föräldrar.
- ett överordnat omfång har inte direkt tillgång till variabler som deklarerats i ett inre omfång.
- Lexical har att göra med var en variabel förklarades / skapades.
- Lexical scope verkställer att hitta variabler från omfattningen / blocket de skapades / deklarerades och inte den miljö som de körs i.
- dynamiskt omfång är motsatsen till lexiskt omfång.
- dynamisk scoping kontrollerar variablerna från var de körs.
Tack för att du läste.
vi ses i nästa inlägg.