Разбиране как работят обхватите в различни сценарии

Програмистът трябва да знае обхвата на променлива, за да знае откъде може да бъде достъпна функцията. Накратко, обхватът е мястото, където можем да получим достъп до променлива или функция.

Съдържание на този блог:

  • Верига на обхвата и вложен обхват
  • Обхват на блок срещу обхват на функция
  • Жизнен цикъл на променливите

За да разберете по-добре работния механизъм на Scopes, трябва да знаете как работи Lexical Scope. В предишния блог обясних механизма на Лексикален обхватиЗатваряния.

Верига на обхвата и вложен обхват

Има 3 обхвата в примерния код по-горе. 3-те обхвата тук са преплетени един с друг. Преплитането на обхватите се нарича вложен обхват. Ако преброим тези обхвати отвътре навън;

  1. Започва с функцията стрелка, която приема числовия параметър на 4-ти ред и завършва с първата къдрава скоба на 6-ти ред.
  2. Започва с функцията getBiggerNumbers на ред 3 и обхваща редовете до фигурните скоби на ред 9.
  3. Всички останали полета са включени в този обхват. В допълнение, този обхват е специално наречен глобален обхват.

Създаден е за по-добро разбиране на горните визуални обхвати. Областта, боядисана в розово, представлява 1.scope. Зелената зона представлява обхват 2. Синята зона е глобален обхват. Обхвати, които имат вложена връзка на обхват един с друг, се наричат ​​вериги на обхват. Тъй като тук има 3 вложени обхвата, този пример също е пример за верига от обхвати.

Обхват на блок срещу обхват на функция

Според Wikipedia, обхватът на функцията може да се дефинира като „Когато обхватът на променливите, декларирани във функция, не се простира отвъд тази функция, това е известно като обхват на функция“. Блоковият обхват се определя като „Обхватът на обвързване на име е блок, който е известен като блоков обхват“. Нека преминем през примера, за да разберем по-добре тези определения.

Фрагментът, който виждате по-горе, е пример за обхват на функцията. Ако сте програмист, който е работил с блоков обхват, вероятно сте мислили, че ще се сблъскате с проблем с тази част от кода. Тъй като името на променливата в 8-ия ред не е дефинирано и съобщението за грешка трябваше да бъде издадено, тъй като се опита да бъде достъпено на 8-ия ред. Но функционалният обхват не работи по този начин. Когато този фрагмент се компилира, лексикалният обхват дефинира име на променлива като недефинирано в горната част на функцията. Поради тази причина името на променливата е достъпно. В допълнение, процесът на преместване на тази променлива в горната част на функцията, което прави лексикалния обхват, се нарича повдигане. Сега нека напишем същата част от кода с блоков обхват и да видим какъв резултат ще получим.

Както можете да видите, това е една от основните причини ключовите думи let и const да са предпочитани пред ключовата дума var в дефиницията на променлива. Тъй като блокът let и const са дефинирани като обхват, те минимизират грешките, които могат да възникнат.

Жизнен цикъл на променливите

Ще проучим как ще се държи дефинирана променлива, когато бъде дефинирана отново със същото име в същия обхват или ако нейната стойност трябва да бъде прочетена, преди да бъде дефинирана променлива. Лексикалният обхват предоставя как и кога може да бъде достъпна променлива.

Функция повдигане:

sum(1 + 3); // 4
function sum(a, b){
	console.log(a+b);
}

Въпреки че функцията за сумиране в кодовия фрагмент се изпълнява, преди да бъде дефинирана, няма грешка. Защо? Лексикалният обхват поставя дефинираната функция за сумиране в горната част на обхвата, в който е била при компилирането. Следователно, когато се извика функцията sum, тя може да се изпълни без грешка. Този процес на преместване се нарича повдигане.

sum(1 + 3); // TypeError: sum is not a function
var sum = function sum(a, b){
	console.log(a+b);
}

Както може да се види в този код, възникнала е грешка. Грешката се връща като TypeError: sum не е функция. Тук Javascript не ни върна нищо, че функцията за сумиране не е дефинирана. Грешката ни казва, че променливата Sum е намерена, но нейната препратка не е функция. Ако Javascript не може да получи достъп до името на променливата sum, той ще върне грешката ReferenceError: sum не е дефинирана. Дефинираната тук функция сума има стойност undefined.

Променливо повдигане:

console.log(name); // undefined
name = 'Caner';
console.log(name); // Caner
var name = "Karaman"
console.log(name); // Karaman

Въпреки че името на променливата, отпечатано на конзолата в първия ред, не е дефинирано преди, то не извежда никаква грешка, докато пише в конзолата. По същия начин тук лексикалният обхват дефинира променливата „име“ като недефинирана в горната част на обхвата. Следователно console.log(име) в първия ред връща undefined вместо да дава грешка. Тъй като променливата за име беше дефинирана в горната част на обхвата с помощта на лексикален обхват, можеше да се присвои стойност на променливата за име във втория ред без никакви ключови думи. Следователно console.log(име) на ред 3 върна „Caner“. Същият процес продължава на 4-ти и 5-ти ред.

За по-добро разбиране, нека разгледаме същия код, след като е бил компилиран.

var name;
console.log(name); // undefined
name = 'Caner';
console.log(name); // Caner
name = "Karaman"
console.log(name); // Karaman

Както можете да видите, лексикалният обхват е взел променливата var и я е преместил в горната част на обхвата. Следователно не се срещат грешки.