Една от най-смущаващите теоретични теми в JavaScript е концепцията зад Closure. В тази статия ще разрешим този „мит“ до възможно най-простата му форма.

Затварянето не е функция, която създаваме, или променлива, която декларираме. Всъщност това е просто процес - процедура - която се случва, когато е създадена от функция. Сега, как се случва, може да попитате. Не бързайте, а първо разгледайте внимателно този код

В горния код можете да видите, че има родителска функция с дъщерна функция. Родителската функция създава обхват и в обхвата имаме декларирана променлива, достъпна за всички дъщерни елементи. Това, както можете да видите, е променливата carNum. Всъщност е зададено на 0. Сега, ако стартирате целия този код във вашия терминал или IDE, той ще върне нарастване на стойността на carNum за всеки път, когато извикате функцията. Това не е ли объркващо? Разбира се, че е! Първо, най-вероятно сте чували, че JavaScript е еднонишков и дори това, за мнозина, не изглежда като цикъл за увеличаване на предварително дефинирана променлива/данни. Това е силата на Затварянето. С прости думи:

Затварянето е способността на функцията да има достъп до променливата(ите), дефинирана преди нея.

В нашата функция по-горе извикахме parentFunc и записахме променливата в parentCaller. Това означава, че върнатата стойност, т.е. това, което искаме от parentFunc да върне (проверете отново функцията), ще бъде запазена в променливата parentCaller и тъй като върнатата стойност е функция, променливата parentCaller също се превръща във функция. Може да се наложи да прочетете този абзац отново, но ако го прочетете и го получите отново, вие сте една крачка по-близо до това да разберете какво е затварянето. Всеки път, когато parentCaller се извиква - тъй като сега е функция - той увеличава стойността на променливата carNum, която е била декларирана преди него и изглежда, че там е проблемът.

Работата е там, че има нещо, наречено Контекст на изпълнение за всеки кодов блок на JavaScript. Има два блока в нашия код; parentFunc и childFunc. Контекстът на изпълнение е „буквално“, когато кодът се изпълнява в стека за извикване, но тази информация всъщност няма значение. По същество, когато стартирате функция или кодов блок, изпълнението излиза и следователно позволява други кодови блокове да бъдат изпълнени. Това е, което по същество се случва. Веднага след като извикате parentFunc и го запазите в parentCaller, той беше изваден от стека от кодови блокове, които Контекстът на изпълнение иска да изпълни и остана childFunc, който остава да бъде изпълнен, но достатъчно смешно, ние го запазихме в променлива надолу по платно. Той се изпълнява всеки път, когато след това го извикате, защото има стойността, която връща childFunc. Смилайте това😊.

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

Надявам се, че тази статия отговори правилно на вашето разбиране за това какво е затваряне. Ако отговорът е да, пуснете коментар и може би относно теми на JavaScript, за които бихте искали да прочетете. С мен, повярвайте ми, JavaScript е по-лесен😊.