├── README.md └── 00_JS_NECƏ_İŞLƏYİR ├── 02_JS_RUNTIME └── README.md ├── 03_EXECUTION_CONTEXT └── README.md ├── 04_CALL_STACK └── README.md ├── 00_ICMAL └── README.md ├── 01_MOTOR └── README.md └── 05_SCOPE_1 └── README.md /README.md: -------------------------------------------------------------------------------- 1 | # Xoş gəlmişsiniz! 2 | 3 | Salam! Mənim adım [Hikmətdir](https://www.linkedin.com/in/iamrajabli/). Bu repo-da Javascript haqqında hər proqramçının bilməli olduğu **kritik** mövzulardan bəhs edirəm. Əgər məlumatlar yararlıdırsa, itirməmək üçün reponu ulduzlamağı (star) unutmayın. 4 | 5 | # Kimlər üçün uyğundur? 6 | Javascript-də heç olmasa müəyyən qədər təcrübəsi olanlar üçün əla qaynaqdır. Yəni 0-dan başlayan biri üçün məs. CALL STACK-da nə baş verdiyini oxumaq məncə sıxıcı olar. 7 | 8 | ## Yeni mövzular 9 | Hər həftə ən az bir mövzu haqqında detallı yazıram. Mövzuların sırası əvvəlcədən var. Odur ki, reponu gündəlik kontrol edin. 10 | 11 | ## Daha yaxşı oxumaq üçün 12 | Sözügedən mövzular olduqca qəlizdir. İlk oxumada aydın olmayan məqamlar çox ola bilər. Təkrar-təkrar oxumaqda fayda var. Adətən oxumaq üçün ən yaxşı vaxt səhər və günorta vaxtlarıdır. Gecə gözünüzdən yuxu töküldüyü zaman bu mövzuları oxumaq vaxt itkisi olacaq. 13 | 14 | ## Unutmayın ki, 15 | Unutmayın ki, mən bu məlumatları dokumentasiyadan və bir sıra mənbələrdən tərcümə edib yazıram. Bu o deməkdir ki, tərcümə xətaları məntiq xətalarına gətirib çıxara bilər. Amma tərcüməni özüm etdiyim üçün bu risk minimum səviyyədədir. Əgər konkret olaraq hər hansı sətirin səhv olduğunu düşünürsünüzsə "**Issues**" bölməsində bunu bildirin. 16 | 17 | Unutmayın ki, yazılan izahlar hər zaman 100% bütöv deyil. Yəni izahlar doğrudur, yazılanlar baş verir amma daha dərində hərşey çox daha mürəkkəb işləyir. İzahlar, iş prinsipini başa düşməyimiz üçündür. 18 | 19 | 20 | ## Müəllif hüquqları 21 | Bu repo hərkəsə açıqdır. Hər hansı müəllif hüququ yoxdur. İstədiyiniz yerdə paylaşın, **amma öz adınızdan paylaşmamaq və mənbə olaraq bu reponu qeyd etmək şərtilə**. Əsasən müəllimlər üçün öz tələbələrinə azərbaycan dilində qaynaq kimi vermək, tələbələr üçün də boş vaxtlarında oxumaq üçün əlverişlidir. 22 | 23 | ## Mentorluq, məsləhət, təklif, şikayət 24 | - [Github](https://github.com/iamrajabli) 25 | - [Linkedin](https://www.linkedin.com/in/iamrajabli/) 26 | - [Facebook](https://www.facebook.com/iamrajabli/) 27 | - [Telegram](https://t.me/iamrajabli) 28 | - [Whatsapp](https://wa.link/ocoumn) 29 | 30 | -------------------------------------------------------------------------------- /00_JS_NECƏ_İŞLƏYİR/02_JS_RUNTIME/README.md: -------------------------------------------------------------------------------- 1 | # Javascript Runtime 2 | 3 | > Javascript Runtime, Javascript proqramlaşdırma dilinin brauzerdə istifadəsi üçün lazım olan hərşeyi özündə cəmləyən bir qutudur (məcazi). Bu qutunun döyünən ürəyi isə Javascript motorudur. 4 | 5 | ### Web API 6 | Javascript kodlarının düzgün şəkildə işləməsi üçün Javascript motoru bəs etmir. Məhz bu problemimizi **[Web API](https://developer.mozilla.org/en-US/docs/Web/API)** aradan qaldırır. Əgər bağlantıya klik etməyə ərindinizsə mən deyim, Web API özündə - DOM, Timers, Fetch API, XMLHttpRequest, Console.log və s. cəmləyir. İndi əhəmiyyətini daha çox başa düşürük. Amma bilmək lazımdır ki, Web API Javascriptin bir hissəsi deyil, sadəcə Javascript onunla **["window"](https://developer.mozilla.org/en-US/docs/Web/API/Window)** obyekti vasitəsilə əlaqə saxlayır. 7 | Bəs Web API nəyin hissəsidir? Cavab: Javascript Runtime-in. 8 | 9 | ### Callback Queue (Callback sırası) 10 | Web API-dən əlavə Javascript Runtime daxilində [Callback sırasına](https://medium.com/@Rahulx1/understanding-event-loop-call-stack-event-job-queue-in-javascript-63dcd2c71ecd) da yer ayırır. Burada bütün yerinə yetirilməyə hazır [callback funksiyalar](https://developer.mozilla.org/en-US/docs/Glossary/Callback_function) yer alır. Məsələn bir butona klik eventi əlavə edib, parametr olaraq callback funksiya göndəririk. Bu butona klik etdikdə həmin callback funksiya: 11 | 12 | 1. Callback sırasına (queue) düşür. 13 | 2. Call Stack təmizlənməsi gözlənilir. 14 | 3. Call Stack təmizləndikdən sonra callback funksiya call stack-ə "**ötürülür**". 15 | 16 | Necə yəni ötürülür? Kim və ya nə ötürür? 17 | 18 | 19 | ### Event Loop (Event döngüsü) 20 | Event loop nəticə etibarilə callback funksiyanı Callback sırasından götürüb Call Stack-ə ötürür. Əgər bundan əvvəlki "[İCMAL](https://github.com/iamrajabli/advanced-js/tree/main/01_JS_NEC%C6%8F_%C4%B0%C5%9EL%C6%8FY%C4%B0R/01_ICMAL)" məqaləsini oxumamısınızsa, qısaca paralellik modelinə (Concurrency model) göz ataq: 21 | 22 | Javascript tək axınlı (single threaded) dildir. Bu o deməkdir ki, bir dəfəyə bir tapşırığı həll edə bilir. Elə bir iş ola bilər ki, həmin iş, axını məşğul edə və özündən sonrakı işlərin gözləməyinə səbəb ola bilər. Bizim bu hallarda köməyimizə - **Event Loop** çatır. 23 | Event loop uzun çəkəcək tapşırıqları götürür və "fon rejimdə" həll edir. Həll etdikdən sonra isə əsas axına (Call Stack) ötürür. Nəticə etibarilə paralel iş prinsipi yaranır. 24 | 25 | ### Bonus məlumat 26 | Web API sadəcə brauzer daxilində əlçatandır. Amma bilirik ki, Javascript brauzer xaricində də [Node.js](https://nodejs.org/en/) sayəsində işləyə bilir. Bu təqdirdə Web API-in yerini "[C++ Bindings & Thread Pool](https://nodejs.org/en/docs/guides/dont-block-the-event-loop/)" alır. 27 | 28 | 29 | ### Unutmayın ki, 30 | 31 | Unutmayın ki, yazılan izahlar hər zaman 100% bütöv deyil. Yəni izahlar doğrudur, yazılanlar baş verir amma daha dərində hərşey çox daha mürəkkəb işləyir. İzahlar, iş prinsipini başa düşməyimiz üçündür. 32 | 33 | #### Mənbələr 34 | 35 | - [Developer Mozilla](developer.mozilla.org) 36 | - [The event loop](https://developer.mozilla.org/en-US/docs/Web/JavaScript/EventLoop) 37 | - [Understanding Event Loop, Call Stack, Event & Job Queue in Javascript](https://medium.com/@Rahulx1/understanding-event-loop-call-stack-event-job-queue-in-javascript-63dcd2c71ecd) 38 | - [Web APIs](https://developer.mozilla.org/en-US/docs/Web/API) 39 | - [Современный JavaScript](https://www.udemy.com/course/javascript-zero-to-junior-developer/) 40 | 41 | -------------------------------------------------------------------------------- /00_JS_NECƏ_İŞLƏYİR/03_EXECUTION_CONTEXT/README.md: -------------------------------------------------------------------------------- 1 | # Execution Context (İcra konteksti) 2 | 3 | ### Global Execution Context (Qlobal İcra konteksti) 4 | Bilirik, ki **yerinə yetirilməyə hazır olan maşın kodu** Call Stack-da işə düşür. İndi baxaq, görək Call Stack-dan əvvəl nə baş verir. 5 | 1. **Üst səviyyəli kodlar üçün Qlobal icra kontekstinin yaradılması ([Global Execution Context](https://medium.com/@happymishra66/execution-context-in-javascript-319dd72e8e2c))** 6 | 7 | Üst səviyyəli kod - Funksiya xaricindəki kodlar. Bu əslində normaldır çünki funksiyalar sadəcə çağrıldıqları zaman işə düşməlidirlər. Eyni zamanda özü özünü çağıran funksiyalar ([IIFE](https://developer.mozilla.org/ru/docs/Glossary/IIFE)) var amma bu bölmənin mövzusu deyil. Qlobal icra konteksti kodun böyüklüyünə baxmayaraq sadəcə bir dəfə yaranır. 8 | 9 | ![enter image description here](https://i.ibb.co/cbWfDY0/900-1200-1200-900-1.png) 10 | 11 | 12 | ### Execution Context (İcra konteksti) 13 | Gəlin, icra kontektsini anlamağa çalışaq. 14 | 15 | > İcra konteksti - Javascript kod parçasının yerinə yetirildiyi mühitdir. 16 | 17 | Belə düşünək, getmişik dönər almağa. Ödənişi edəndən sonra bizə bir paketdə dönər verilir. Həmin paketin içində həm dönər həm salfetka həm də xahiş etdiyimiz acı bibərlər var (bibərsiz dadı olmur). Bu analogiya üzrə həmin paket bizim icra kontekstimiz, dönər, salfetka və bibərlər bizim kodlarımızdır. Yəni icra konteksti nəticə etibarilə müəyyən prosesi yerinə yetirmək üçün özündə Javascript kodlarını cəmləyir. Müəyyən proses isə bizim dönəri və bibərləri yeməyimiz, salfetka ilə əlimizi, ağzmızı (sonra da ayaqqabımızı) silməyimizdir. 18 | 19 | 2. **Bu addımda artıq qlobal icra kontekstindəki kodlar yerinə yetirilir. Yəni prosessor maşın kodunu işləyir.** 20 | 21 | 3. **Nəhayət funksiyalar və call back funksiyalar yerinə yetirilir.** 22 | 23 | Burda nəzərə almaq lazımdır ki, hər funksiya çağırışına (invoke) görə yeni bir icra konteksti yaranır. Bütün funksiyalar yükləndikdən sonra Javascript motoru call back funksiyaları gözləyir. 24 | 25 | Yaxşı, hərşeydən danışdıq. Amma hələ də bilmirik ki, icra konteksti daxildə nədən ibarətdir: 26 | 27 | 1. **Variable Environment** 28 | - let, const və var ilə deklarasiyalar 29 | - funksiyalar 30 | - **arugments** obyekti - funksiyanın aldığı parametrlər. 31 | 32 | 2. **Schope Chain** 33 | Funksiyalar xaricdəki dəyişəndən istifadə edə bilər. Bu Schope Chain sayəsində baş verir. Bu mövzunu çox detallı müzakirə edəcəyik. 34 | 35 | 3. **this** - Bu mövzunu da çox detallı müzakirə edəcəyik. 36 | 37 | **Diqqət!** 38 | [Arrow funksiyalar](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/Arrow_functions) arguments və this-i ehtiva etmir. Bilməyənlər narahat olmayın bu cür funksiyaları da detallı müzakirə edəcəyik. 39 | 40 | Nəticə: Kodlarımızı işə saldıqda [müəyyən prosesləri](https://github.com/iamrajabli/advanced-js/tree/main/01_JS_NEC%C6%8F_%C4%B0%C5%9EL%C6%8FY%C4%B0R/02_MOTOR) keçərək maşın koduna çevrilir. Bu prosesdən sonra qlobalda yaradılan dəyişənlər və s. üçün, kodların həcminə baxmayaraq sadəcə bir dənə **qlobal icra konteksti** yaranır. Daha sonra funksiyaların hər birinə görə yeni icra konteksti yaranır. Bu icra kontekstinin içində də **variable environment, scope chain və this** var. 41 | Variable environment daxilindəki arguments və this mövcudluğu funksiyanın arrow funksiya olmamasından aslıdır. 42 | 43 | Gəlin şəkildəki kodların yaratdığı qlobal və icra kontekstlərinin içində nə baş verdiyinə baxaq. 44 | 45 | ![enter image description here](https://i.ibb.co/bQ3pV4P/Screenshot-3.png) 46 | 47 | Yuxarıdakı şəkildəki kodlardan bir qlobal icra konteksti və iki icra konteksti çıxır. 48 | 49 | 50 | **Global icra konteksti** 51 | - greeting = **'Hello!'** 52 | - smth = <**function**> 53 | - foo = <**function**> 54 | - num = <**unknown**> 55 | 56 | **İcra konteksti - smth()** 57 | - k = 3 58 | - d = <**unknown**> 59 | 60 | **İcra konteksti - foo()** 61 | - x = 5 62 | - arguments = [4, 5] 63 | 64 | Kontekstlər belədir. Qeyd edilən unknown-lar isə həmin funksiyanın işə düşmədiyi üçündür, işə düşdüktən sonra alınan nəticə ilə yerini dəyişəcəklər. 65 | 66 | Yaxşı burda belə sual yaranır. Tutaq ki, kodumuzda yüzlərcə funksiya var. Bu o deməkdir ki, yüzlərcə də icra konteksti yaranır. Yaxşı bəs Javascript motoru bunu necə sıralayacaq və necə yerinə yetirəcək? 67 | Burada isə **Call Stack** köməyimizə çatır. Bu da bir sonranın mövzusudur. 68 | 69 | ### Unutmayın ki, 70 | Unutmayın ki, yazılan izahlar hər zaman 100% bütöv deyil. Yəni izahlar doğrudur, yazılanlar baş verir amma daha dərində hərşey çox daha mürəkkəb işləyir. İzahlar, iş prinsipini başa düşməyimiz üçündür. 71 | 72 | #### Mənbələr 73 | 74 | - [Developer Mozilla](developer.mozilla.org) 75 | - [JavaScript Execution Context](https://www.freecodecamp.org/news/execution-context-how-javascript-works-behind-the-scenes/) 76 | - [Контекст выполнения и стек вызовов в JavaScript](https://habr.com/ru/company/ruvds/blog/422089/) 77 | - [Современный JavaScript](https://www.udemy.com/course/javascript-zero-to-junior-developer/) 78 | 79 | 80 | -------------------------------------------------------------------------------- /00_JS_NECƏ_İŞLƏYİR/04_CALL_STACK/README.md: -------------------------------------------------------------------------------- 1 | # Call Stack 2 | 3 | > Call stack - İcra prosesində harada olduğumuzu izləmək üçün icra kontekstlərinin üst-üstə yığıldığı yerdir. 4 | 5 | [Keçən mövzumuz](https://github.com/iamrajabli/advanced-js/tree/main/01_JS_NEC%C6%8F_%C4%B0%C5%9EL%C6%8FY%C4%B0R/04_EXECUTION_CONTEXT) (əgər keçən mövzunu oxumamısınızsa lütfən oxuyun) olan İcra kontekstində belə bir sual yarandı: - "Tutaq ki, kodumuzda yüzlərcə funksiya var. Bu o deməkdir ki, yüzlərcə də icra konteksti yaranır. Yaxşı bəs Javascript motoru bunu necə sıralayacaq və necə yerinə yetirəcək?" 6 | 7 | ### Call Stack iş prinspi 8 | 9 | Keçən mövzuda aşağıdakı şəklin izahını vermişdim. 10 | 11 | ![enter image description here](https://camo.githubusercontent.com/06dee3cc7884a5f1c3a425a988d13da413563d785bea18981adc2569d0de3c09/68747470733a2f2f692e6962622e636f2f625133705634502f53637265656e73686f742d332e706e67) 12 | 13 | **İcra kontekstində:** 14 | 15 | ***Global icra konteksti*** 16 | 17 | - greeting = **'Hello!'** 18 | - smth = <**function**> 19 | - foo = <**function**> 20 | - num = <**unknown**> 21 | 22 | ***İcra konteksti - smth()*** 23 | 24 | - k = 3 25 | - d = <**unknown**> 26 | 27 | ***İcra konteksti - foo()*** 28 | 29 | - x = 5 30 | - arguments = [4, 5] 31 | 32 | İndi keçək bu kontekstlərin Call Stack-da saxlanılmasına 33 | 34 | **Call Stack-də:** 35 | 36 | **1. Call stack-də ilk yerini alan data - Qlobal icra kontekstidir.** 37 | - greeting = **'Hello!'** 38 | - smth = <**function**> 39 | - foo = <**function**> 40 | - num = <**unknown**> 41 | 42 | ![enter image description here](https://i.ibb.co/RbTHK5k/1480-1080.png) 43 | 44 | 2. İkinci addımda 45 | 46 | Keçən dəfəki örnəkdə ən son sətirdəki kod parçası işə düşür: 47 | 48 | const num = smth(); 49 | 50 | Bu halda **"smth"** funksiyası işə düşür və yeni bir icra konteksti yaranır, beləliklə Call stack-də öz yerini alır. 51 | 52 | ***İcra konteksti - smth()*** 53 | 54 | - k = 3 55 | - d = <**unknown**> 56 | 57 | ![enter image description here](https://i.ibb.co/NjJR1BS/1480-1080-1.png) 58 | 59 | 60 | 3. Üçüncü addımda smth() funksiyasının yaratdığı icra kontekstində aşağıdakı kodun oxunması nəticəsində foo() funksiyası işə düşür və yeni icra konteksti yaranır, beləliklə Call stack-də öz yerini alır. 61 | 62 | 63 | 64 | const d = foo(4,5); 65 | 66 | 67 | ![enter image description here](https://i.ibb.co/F6xSc4k/1480-1080-2.png) 68 | 69 | 70 | 71 | 72 | 73 | **Birşeyi başa düşmək çox önəmlidir.** Fikir verirsinizsə "const d = foo(4,5)" sətrindən sonra da kodlar var idi. Amma bu sətir oxunandan sonra yeni icra konteksti yarandı və bu kontekst Call Stack-a əlavə edildi. 74 | 75 | **Bu halda, yeni yaranan kontekst, Call Stack-da aktiv icra konteksti olur. Yəni ondan əvvəlki icra kontekstinin icrasına pauza verilir. Nə vaxt ki, yeni kontekstin icrası bitəcək, onda əvvəlki kontekstin icrası qaldığı yerdən davam edəcək. Yəni sadəcə bir kontekstin icrası baş tuta bilir. Bu Javascript-in tək axınlı (single thread) dil olduğuna görədir.** 76 | 77 | 78 | 79 | 4. Dördüncü addımda **foo()** funksiyasının son sətrindəki **return x** kodu işə düşəcək və funksiya sonlanacaq. Bəs bu Call Stack üçün nə deməkdir? 80 | 81 | ![enter image description here](https://i.ibb.co/CWkH3nP/1480-1080-3.png) 82 | 83 | Bilirəm, şəkil ağlınızı qarışdırır. Bu o deməkdir ki, funksiya **foo()** işini bitirdi və Call Stack-dan silindi **(bəzi hallarda Call Stack-dan silinən məlumatlar yaddaşda qalmağa davam edir. Bu barədə sonrakı mövzularda bəhs edəcəyik).** İndi **smth()** funksiyası yenidən aktivdir və qaldığı yerdən (k+=d) davam edəcək yuxarıda qeyd etdiyimiz kimi. 84 | 85 | 5. Beşinci addımda, **smth()** funksiyasının yaratdığı icra konteksti də bitdikdən sonra Call Stack-dan silinir. 86 | 87 | ![enter image description here](https://i.ibb.co/rsBSx2w/1480-1080-4.png) 88 | 89 | Geriyə qlobal icra konteksti qaldı. Kod sətrində isə qaldığımız yerdən (**"const num = smth()"**) davam edirik. Artıq **smth()** funksiyasından geri dönən dəyər **num** dəyişəninə göndərildi. 90 | 91 | 6. Altıncı və sonuncu addımda **brauzerin pəncərəsi bağlandıqda** qlobal icra konteksti də Call Stack-dan silinir. 92 | 93 | Diqqət - İcra konteksti, istifadəçi tərəfindən həyata keçirilən müxtəlif proseslərin nəticəsində də Call Stack-dan silinə bilər. Məsələn, komputer söndürüldükdə, brauzer bağlandıqda və s. 94 | 95 | ### Son olaraq hərşeyin tam oturması üçün qısametrajlı qorxu filmi: 96 | **Siz** proqramçılıqdan bezib Bolt-da taksi fəaliyyətinə başlamısınız. **Müştəri** N. Nərimanov metrosuna taksi **sifariş verib**. Siz də hər zaman sifariş üçün Nizami metrosunda gözləyirsiniz amma sifariş nöqtəsinə necə gedəcəyiniz barəsində bir fikriniz yoxdur. Amma şanslısınız, çünki **Google map** var. Google map sayəsində N. Nərimanov metrosuna yola düşürsünüz, sifarişi tamamlayırsınız və Nizami metrosuna geri qayıdırsınız. 97 | 98 | **Rollarda:** 99 | - Siz: **Javascript motoru** 100 | - Müştəri: **Proqramçı** 101 | - Sifariş: **İcra kontekstləri** ([Tom Hardy Legend](https://www.imdb.com/title/tt3569230/)) 102 | - Google map: **Call Stack** 103 | 104 | ### Unutmayın ki, 105 | Unutmayın ki, yazılan izahlar hər zaman 100% bütöv deyil. Yəni izahlar doğrudur, yazılanlar baş verir amma daha dərində hərşey çox daha mürəkkəb işləyir. İzahlar, iş prinsipini başa düşməyimiz üçündür. 106 | 107 | #### Mənbələr 108 | - [Developer Mozilla](https://developer.mozilla.org) 109 | - [Call stack](https://developer.mozilla.org/en-US/docs/Glossary/Call_stack) 110 | -------------------------------------------------------------------------------- /00_JS_NECƏ_İŞLƏYİR/00_ICMAL/README.md: -------------------------------------------------------------------------------- 1 | 2 | # Javascript icmal 3 | 4 | > **Javascript bir neçə paradiqmaya malik yüksək səviyyəli obyekt-yönümlü dildir** 5 | 6 | ### Yüksək səviyyəli dil 7 | Yazdığımız proqramın kompüterimizdə çalışa bilməsi üçün bəzi resurslara sahib duyuruq (hardware) - yaddaş, prosessor və s. YSD-lərdə bu resurslar manual olaraq idarə edilmir (JS, Python və s.). Lakin aşağı səviyyəli dillərdə isə resurslar manual olaraq idarə edilməlidir (C, C++ və s.). YSD-lər bu xüsusiyyətlərinə görə öyrənmək və istifadə etmək üçün daha uyğundurlar. Əlavə olaraq, YSD özü ilə bərabər bir minus gətirir. YSD ilə yazılan proqramlar ASD ilə yazılanlara nəzərən "çox optimal və sürətli" ola bilmirlər. 8 | 9 | ### Zibil toplayıcı (Garbage collector) 10 | Yuxarıda sözügedən Javascript xüsusiyyətlərindən biri də zibil toplama alqoritminə sahib olmasıdır. Bu alqoritim avtomatik olaraq yaddaşı təmizləyir yəni lazım olmayan obyektləri yaddaşdan silir. 11 | 12 | ### Interpreted və ya JIT 13 | Aydındır ki, kompüter yazdığımız kodları başa düşmür. Başa düşməsi üçün kodlarımızı 0 1 kimi tərcümə edən texnologiyaya ehtiyac duyuruq. Javascript-də yazdığımız kodları (sözləri) anlayışı olmayan birinə göstərsək də müəyyən bir anlayış sahibi ola bilər (for, if, function, return, getElementById və s.). Yazdığımız bu kodlar "0 1 üzərində abstraksiya" adlanır. Günün sonunda yazdığımız kodlar ya interpretasiya ya da kompilyasiya nəticəsində maşın koduna (0 1) çevriləcəkdir. Bəs Javascript kodlarımız hansı texnologiya sayəsində maşın koduna çevirilir? - Brauzerlərdəki Javascript motorları sayəsində (V8, Carakan, SpiderMonkey və s.) 14 | 15 | ### Multiparadiqma 16 | Paradiqma - kodun yazılma üslubunu və texnikasını təyin edəcək kodu strukturlaşdırmaq üçün yanaşma və düşüncə tərzidir. 17 | Bir proyektdə müəyyən paradiqma istifadə olunur. Proqramlaşdırmada 3 məşhur paradiqma var: Prosessual, funksiyonal, obyekt-yönümlü (OOP). Javascript bu paradiqmaların üçünü də istifadə edə bilir. 18 | 19 | 20 | ### Prototip əsaslı obyekt-yönümlü (Prototype-based object-oriented) 21 | Əvvəlcə bilmək lazımdır ki, Javascript-də hərşey obyektdir (primitiv tiplər xaric). Məsələn istifadə etdiyimiz massivlər əslində bir obyektdir. Aşağıdakı nümunədə göründüyü kimi: 22 | 23 | const someArr = [1, 2, 3, 4]; 24 | someArr.push(5); 25 | const filteredArr = someArr.filter(item => item > 2); 26 | 27 | Bir massiv yaradırıq və o massivə **push** metodu ilə bir rəqəm əlavə edirik daha sonra **filter** metodu ilə 2-dən böyük olanlardan yeni bir array yaradırıq. Sual yaranır - necə biz hər yaratdığımız massivdə eyni metodları istifadə edə bilirik? Bu **prototip əsaslı miras** nəticəsində meydana gəlir. Bu o deməkdir ki, Javascriptdə Array adında bir sinif (class) və bu sinifin özündə cəmlədiyi metodlar (forEach, map, includes, push, filter və s.) var. Aşağıdakı nümunədəki kodun: 28 | 29 | console.log(Array.prototype); 30 | 31 | Konsola çıxardığı nəticə aşağıdadır. 32 | 33 | ![prototype](https://i.ibb.co/GFJ94Z7/index.png) 34 | 35 | Bu şəkildən aydın olur ki, yaratdığımız hər massiv bu metodları miras alır. Elə buna görə də biz hər massivdə bu metodları istifadə edə bilirik. 36 | Bu mövzu olduqca böyükdür. OOP bölməsində çox daha detallı bəhs edəcəyik. 37 | 38 | ### Birinci sinifdən funksiyalar (First-class function) 39 | Javascriptdə funksiyalar dəyişən (variable) kimi hesab olunur (expression və ya regular-dan fərqindən söhbət getmir). Elə bu səbəbdən də funksiyaları başqa funksiyalara parametr olaraq göndərə və hər hansı funksiyadan geriyə funksiya qaytara bilirik. Aşağıdakı nümunədə bir funksiyanı başqa funksiyaya göndərmişik. 40 | 41 | function clickHandler(e) { 42 | console.log(e.target, this); 43 | } 44 | 45 | window.addEventListener('click', clickHandler); 46 | 47 | ### Dinamik 48 | Javascript dinamik tipizasiyaya sahib dildir. Yəni dəyişən yaratdığımız zaman dəyişənin hansı tipdə olduğunu dilin özü təyin edir (Number, String, BigInt və s.). Bu xüsusiyyət bütün proqramlaşdırma dillərində yoxdur. Məsələn C++, Java, C# kimi dillərdə dəyişən yaradılan zaman tipi də təyin edilməlidir. Javascript kodları ilə statik tipizasiya üçün [Typescript](https://www.typescriptlang.org/) proqramlaşdırma dili istifadə olunur. 49 | 50 | ### Tək axınlı (Single threaded) 51 | Axın ([thread](https://www.iitk.ac.in/esc101/05Aug/tutorial/essential/threads/definition.html)) nədir? - Axın, çox sadə dillə desək, kompüterin prosessorunda kodun işlədiyi yerdir. 52 | Javascript tək axınlı (single threaded) dildir. Bu o deməkdir ki, bir dəfəyə sadəcə bir tapşırığı həll edə bilir. 53 | 54 | ### Paralellik modeli (Concurrency model) 55 | Qeyd etdiyimiz kimi Javascript tək axınlı (single threaded) dildir. Bu o deməkdir ki, bir dəfəyə bir tapşırığı həll edə bilir. Elə bir iş ola bilər ki, həmin iş, axını məşğul edə və özündən sonrakı işlərin gözləməyinə səbəb ola bilər. Bizim bu hallarda köməyimizə - **Event Loop** çatır. 56 | Event loop uzun çəkəcək tapşırıqları götürür və "fon rejimdə" həll edir. Həll etdikdən sonra isə əsas axına ötürür. Nəticə etibarilə paralel iş prinsipi yaranır. 57 | 58 | ### Unutmayın ki, 59 | 60 | Unutmayın ki, yazılan izahlar hər zaman 100% bütöv deyil. Yəni izahlar doğrudur, yazılanlar baş verir amma daha dərində hərşey çox daha mürəkkəb işləyir. İzahlar, iş prinsipini başa düşməyimiz üçündür. 61 | 62 | #### Mənbələr 63 | 64 | - [Developer Mozilla](developer.mozilla.org) 65 | - [High-Level Language (HLL)](https://www.techopedia.com/definition/3925/high-level-language-hll) 66 | - [Memory management](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Memory_Management) 67 | - [Thread](https://en.wikipedia.org/wiki/Thread_(computing)) 68 | - [Современный JavaScript](https://www.udemy.com/course/javascript-zero-to-junior-developer/) 69 | 70 | -------------------------------------------------------------------------------- /00_JS_NECƏ_İŞLƏYİR/01_MOTOR/README.md: -------------------------------------------------------------------------------- 1 | # Javascript motoru 2 | 3 | > Javascript motoru - Javascript kodlarını yerinə yetirən **proqramdır**. Yəni motor deyəndə ağıla porşenlər, silindirlər və s. gəlməməlidir. Hər brauzerin özünün Javascript motoru var. Aralarında ən məşhur **V8** motorudur. 4 | 5 | ### V8 6 | V8 motoru Google Chrome brauzerində işləyir. Əlavə olaraq Node.js bu motorun köməyilə işləyir. Lütfən, Node.js-in proqramlaşdırma dili olduğunu düşünməyin. Node.js bir "**[runtime environment](https://www.techopedia.com/definition/5466/runtime-environment-rte)**"-dir. Təəssüf ki, azərbaycan dilinə tərcüməsi (~~iş vaxtı mühiti~~), onu anlamağa çox da kömək etmir. Node.js sayəsində Javascript kodlarını server tərəfdə işlətmək mümkündür. 7 | 8 | ### Motorların işləmə prinsipi 9 | Hər Javascript motoru **"Call Stack və Heap"**-ə sahibdir. 10 | **Call Stack** - bu hissədə yazdığımız kodlar yerinə yetirilir. 11 | **Heap** - Struktursuz yaddaş hissəsi. Bu hissədə Javascript kodları ilə yaratdığımız bütün obyektlər yer alır. 12 | 13 | ![enter image description here](https://i.ibb.co/n1NrmNh/1-On-H-Dlb-NAPv-B9-KLx-UCy-Ms-A.png) 14 | 15 | 16 | 17 | ### Kompilyasiya və interpretasiya 18 | Kompüterlərin sadəcə 0 və 1-ləri (maşın kodu) başa düşdüyündən danışmışdıq. Ona görə də bütün proqramlaşdırma dillərində yazılan kodlar günün sonunda maşın koduna çevrilməlidir. Bu proses ya kompilyasiya ya da interpretasiya yolu ilə baş tutur. 19 | 20 | **Kompilyasiya** - Bütün kod dərhal maşın koduna çevrilir və kompüterdə icra oluna bilən ikili fayla yazılır. İkili fayldan nümunə aşağıdadır: 21 | 22 | ![enter image description here](https://i.ibb.co/hmdh0gL/ZOa00.png) 23 | 24 | İndi gəlin kompilyasiya addımlarına baxaq: 25 | 26 | 1. Mənbə kodu (yazdığımız normal kodlar) 27 | 2. Kompilyasiya (bütün kodların maşın koduna çevrilməsi) 28 | 3. Maşın kodu ([portativ](https://www.azleks.az/az/online-dictionary/portativ) fayl) 29 | 4. Yerinə yetirmə (istifadəçi tərəfindən) 30 | 31 | Yazılan addımlar sizi çaşdırmasın. Belə düşünün, kompüterinizdəki proqramlar artıq kompilyasiyası başa çatmış proqramlardır. Yəni 3 cü addımı bitiriblər. Siz klikləyib açanda 4 cü addımdan başlayırsınız. Yəni proqramı başladırsınız. Məncə bu səfər super-aydındır. 32 | 33 | **İnterpretasiya** - Bu proses zamanı interpretator kodları sətir-sətir yerinə yetirir. Yəni sətir-sətir maşın koduna çevirir. 34 | 35 | Sizcə kompilyasiya edilmiş proqram **döyər** yoxsa sətir-sətir yerinə yetirilən proqram? Əlbətdə kompilyasiya edilmiş proqram! Təsəvvür edin NASA-da kosmosdakı gəmilərin koordinatını izləyən işçi gəminin hərəkəti zamanı prosesin sətir-sətir işlənməsini gözləyir. 36 | 37 | ~~Javascript interpretasiya olunan dildir!~~ 38 | Yəqin ki, siz də Javascript-in interpretasiya olunan dil olduğunu düşünürsünüz. Yaxşı ki, yanılırsınız. Müasir Javascript özündə həm kompilyasiyanı həm də interpetasiyanı cəmləyir. Bu proses JIT compilation (Just in time compilation) adlanır. Gəlin burdaki (JIT compilation) addımlara baxaq. 39 | 40 | 1. Mənbə kodu (yazdığımız normal kodlar) 41 | 2. Kompilyasiya (bütün kodların maşın koduna çevrilməsi) 42 | 3. Maşın kodu və proqramın dərhal yerinə yetirilməsi. 43 | 44 | Bu addımlar daha qəlizdir sanki. 45 | 46 | **İndi də belə düşünək:** 47 | 48 | **Normal interpretasiya** zamanı kodlar sətir-sətir maşın koduna çevrilirdi və işə düşürdü. Bu o demək idi ki, hər proqramı istifadə etdiyimiz zaman kodlar yenə sətir-sətir maşın koduna çevriləcək. Bu sürətimizi azaldırdı. 49 | 50 | **Kompilyasiya** zamanı kodların hamsı maşın koduna çevrilirdi və yeni fayl əldə edirdik. İstədiyimiz zaman onu işə salırdıq. Hər işə saldığımız zaman yenidən maşın koduna çevirmə baş vermirdi. Bu da sürətimizi artırırdı. 51 | 52 | **JIT** kompilyasiya zamanı isə kodlarımız sətir-sətir maşın koduna kompilyasiya olmur, hamsı birdən kompilyasiya olur. Normal kompilyasiyada olduğu kimi bir fayl əldə edib onu təkrar-təkrar işə sala bilmirik. Sadəcə hər işə saldıqda kodların hamsı kompilyasiya olub işə düşür. 53 | 54 | 55 | ### Javascript kod parçası Javascript motoruna daxil olur... 56 | Javascript kod parçası motora daxil olduğu zaman **ilk mərhələ Parsinq mərhələsidir.** Parsinq mərhələsində bütün kodlar müəyyən əhəmiyyəti olan hissələrə bölünür. Məsələn aşağıdakı nümunyə baxaq. 57 | 58 | Parsindqən əvvəl: 59 | 60 | const info = "Məlumatlar yararlıdırsa, reponu itirməmək üçün ulduzlayın (star)." 61 | 62 | Parsindqən sonra: 63 | 64 | 65 | ![enter image description here](https://i.ibb.co/p25S5hs/Screenshot-2.png) 66 | 67 | Bu sintaksis **[AST](https://astexplorer.net/)** **(Abstract syntax trees)** adlanır. Bu mərhələdə həm də sintaktik xətalar yoxlanılır. Lütfən AST-ni DOM tree ilə qarışdırmayın. 68 | 69 | İkinci mərhələdə isə AST-in maşın koduna (0 və 1) kompilyasiyası baş verir və bu maşın kodu dərhal işə düşür. Maşın kodunun işə düşməsi **CALL STACK**-da baş verir. 70 | 71 | Müasir Javascript motorları ağıllı optimallaşdırma sisteminə sahibdirlər. Bu sistem sayəsində ikinci mərhələdə çox da optimal olmayan maşın kodu versiyası əldə edirik. Bu ona görədir ki, proqram maksimum səviyyədə sürətli işə düşsün və fonda (arxa planda) yenidən kompilyasiya olunaraq optimallaşsın. Fonda optimallaşma zamanı bunu hiss etmirik amma nəticədə işə düşən proqram sonda optimal olur. Bu optimallaşdırma bir neçə dəfə baş verə bilər. Yəni hər optimallaşdırma zaman optimal maşın kodu əvvəlki maşın kodunu əvəz edir. Məhz bu optimallaşdırma sistemi sayəsində müasir Javascript motorları olduqca sürətlidir. 72 | 73 | P.S - Yuxarıdakı mərhələlərə müdaxilə edə bilmirik. Çünki bu mərhələlər əsas axında (main thread) deyil, ayrı axında baş verir. Əsas axın **CALL STACK**-da işə düşür. 74 | 75 | İndi könül rahatlığı ilə Javascript interpretasiya olunan dil deyil deyə bilərsiniz! 76 | 77 | 78 | ### Unutmayın ki, 79 | 80 | Unutmayın ki, yazılan izahlar hər zaman 100% bütöv deyil. Yəni izahlar doğrudur, yazılanlar baş verir amma daha dərində hərşey çox daha mürəkkəb işləyir. İzahlar, iş prinsipini başa düşməyimiz üçündür. 81 | 82 | #### Mənbələr 83 | 84 | - [Developer Mozilla](developer.mozilla.org) 85 | - [JIT-компиляция](https://ru.wikipedia.org/wiki/JIT-%D0%BA%D0%BE%D0%BC%D0%BF%D0%B8%D0%BB%D1%8F%D1%86%D0%B8%D1%8F) 86 | - [Abstract syntax trees (AST) ](https://www.dc.fi.udc.es/staff/freire/coqdoc/pauillac.inria.fr/coq/doc/n102.htm) 87 | - [What is V8?](https://v8.dev/) 88 | - [Современный JavaScript](https://www.udemy.com/course/javascript-zero-to-junior-developer/) 89 | 90 | -------------------------------------------------------------------------------- /00_JS_NECƏ_İŞLƏYİR/05_SCOPE_1/README.md: -------------------------------------------------------------------------------- 1 | ## Scope - I hissə 2 | 3 | > Scope, bu suallara cavab verir: *Dəyişənlər (variables) harada yaşayır və müəyyən dəyişənə necə çatmaq olar?* 4 | 5 | ![enter image description here](https://i.ibb.co/3kC7Mnb/1-Kx-Hw-Vb-B0zhn-SVrhr-Wt-T-gg.jpg) 6 | 7 | Javascript-də aşağıda qeyd olunan scope anlayışları mövcuddur: 8 | 9 | 1. **Global scope** 10 | 11 | ![enter image description here](https://i.ibb.co/TbsvpSc/image.png) 12 | 13 | Yuxarıdakı koddakı dəyişən əgər bütün funksiyaların və blokların xaricindədirsə global scope sayılır. Bu dəyişənə kodun istənilən yerində (təyin olunduğu yerdən aşağı. İstisna, bax. **[hoisiting](https://www.w3schools.com/js/js_hoisting.asp))** çatmaq mümkündür. 14 | 15 | 2. **Function scope** 16 | 17 | 18 | `Function scope` - da dəyişənlər funksiyaların içində yaradılır və kənardan əlçatan olmurlar. 19 | 20 | ![enter image description here](https://i.ibb.co/SX3dQXw/image.png) 21 | 22 | 23 | 3. **Block scope (ES6)** 24 | 25 | `Block scope` - da dəyişənlər sadəcə blokun içində əlçatan olurlar. Lakin bu sadəcə `const` və `let` ilə yaradılan dəyişənlərə aiddir. `var` açar sözü ilə yaradılan dəyişənlər kənaradan da əl çatan olurlar (bax. **[беспредел](https://ru.wikipedia.org/wiki/%D0%91%D0%B5%D1%81%D0%BF%D1%80%D0%B5%D0%B4%D0%B5%D0%BB))** 26 | 27 | Bu arada maraqlı birşey - funksiyalar da öz içlərində `block scope` - a sahib ola bilirlər. 28 | 29 | ![enter image description here](https://i.ibb.co/BTwmhM0/image.png) 30 | 31 | 32 | ## Nümunələr 33 | 34 | ### Global scope 35 | 36 | Dediyimiz kimi `global scope` - də yaradılan dəyişənə hər yerdən müraciət edə bilirik: 37 | 38 | ![enter image description here](https://i.ibb.co/WtfXcr9/image.png) 39 | 40 | Biraz uzadaq: 41 | 42 | ![enter image description here](https://i.ibb.co/FqVZrQp/image.png) 43 | 44 | 45 | Yuxarıda bir istisnadan danışmışdıq qlobal scope ilə əlaqəli: 46 | 47 | ![enter image description here](https://i.ibb.co/0MSM30T/image.png) 48 | 49 | 50 | Niyə belə birşey edəsən amma bunu hoisting ilə həll etmək olar: 51 | 52 | ![enter image description here](https://i.ibb.co/BTGZzL7/image.png) 53 | 54 | Sizə `var` ilə əlaqəli maraqlı birşey deyim. Adətən bu məlumat çox yerdə verilmir. Sadəcə deyilir ki, "Modern javascriptdə var yerinə `let` və ya `const` istifadə edin." Yaxşı bəs niyə? Qardaş mənim ürəyim `var` istifadə etmək istəyir. Elə bir səbəb de ki istifadə etməyim yoxsa hər şey modern olsun deyə dəyişməzki. 55 | 56 | #### Demək: Javascript'də `var` ilə yaradılan dəyişənlər `window` obyektinə (özünüz birin yaradıb yoxlayın) düşür. Elə buna görə də aşağıdakı performans məsələləri yaranır: 57 | 58 | 1. Lazımsız yaddaş istifadəsi: `var` ilə yaradılan dəyişənlər `window` obyektində saxlanıldığı üçün, lazımsız yaddaş istifadəsinə səbəb ola bilər. Xüsusilə böyük tətbiqlər və çox sayda dəyişənin tanımlandığı halda önəmli bir performans itkisi baş verə bilər 59 | 60 | 2. Toqquşmalar: `window` obyektinə düşən dəyişənlər, digər kitabxanalar tərəfindən də istifadə edilə bilər. Bu vəziyyətdə, dəyişən adları arasında toqquşmalar yarana bilər və gözlənilməz xətalara səbəb ola bilər. 61 | 62 | 3. Təhlükəsizlik açıqları: `var` ilə yaradılan dəyişənlər, `window` obyektinə düşür və bu səbəbdən digər kodlar (bizim və ya qeyri-bizim tərəfdən yazılan) tərəfindən dəyişdirilə bilər. Bu, potensial təhlükəsizlik açıqlarına səbəb ola bilər və kodun işlənməsini mənfi təsir edər. 63 | 64 | Məncə yetərincə aydın oldu artıq niyə `const` və `let` istifadə etmək lazımdır. Təbii ki, `const` və `let`-də bu hadisə baş vermir. 65 | 66 | ### Block scope 67 | 68 | ![enter image description here](https://i.ibb.co/TqSZBVR/image.png) 69 | 70 | `For`, `if`, `while` və s. `block scope` - a sahibdir ( {} ). Göründüyü kimi blokun içində təyin edilən `a` dəyişəninə blokun xaricində çatmaq olmur. 71 | 72 | ![enter image description here](https://i.ibb.co/9ttQx7d/image.png) 73 | 74 | Hər `block scope` bir `local scope` - a sahibdir. İndi deyəcəksiniz ki, lokal-mokal hardan çıxdı amma adından da göründüyü kimi hər blok, `local scope` - a sahibdir. Əslində bu çox məntiqlidir. `keyCopy` dəyişəni təyin edilir və blokun içində yaradılan yeni blokda əl çatan olur. Amma bunun əksi mümkün deyil. Yəni `child block`-un içində yaradılan dəyişən `parent block`-dan çağrılmır (const, let). 75 | 76 | ![enter image description here](https://i.ibb.co/mhgxqDM/image.png) 77 | 78 | Sözü gedən məsələyə yuxarıdakı şəkildə toxundum. Göründüyü kimi `b` dəyişəninə əsas blokda çata bilmirik. 79 | 80 | 81 | ### Function scope 82 | 83 | Block scope nümunəsində local scope haqqında danışdıq. İndi gəlin `lexical scope` nədir buna da baxaq. Maraqlı söhbətdir hətta local scope ilə qarışdırılır tez-tez. Təkrarlayaq - local scope deyəndə bunu yada salmaq lazımdır - bir dəyişkən yaradıldığı blok daxilində əlçatandır. Yəni o blokun içində bir blok da yaratsan yaradılan blok dəyişənin yaradıldığı blokda olduğu üçün həmin dəyişən onda da əlçatandır. Lakin bir funksiyanın içində digər bir funksiya yarandığı zaman `child function` - un, `parent function`-un parametrlərinə və daxilində yaranan dəyişənlərə çata bilməsi `lexical scope` adlanır. 84 | 85 | ![enter image description here](https://i.ibb.co/k8ssPd4/image.png) 86 | 87 | Sadəcə daxilindəki dəyişənlərə yox həm də parametrlərdə `child function` tərəfindən əl çatan olur. 88 | 89 | ![enter image description here](https://i.ibb.co/Lz11R7T/image.png) 90 | 91 | 92 | Bəs əksi mümkündür mü? Yəni `child function`-da yaradılan dəyişəni `parent function`-da çağıra bilərik mi? yox təbiiki. 93 | 94 | ![enter image description here](https://i.ibb.co/NTCs1Fm/image.png) 95 | 96 | Əslində `lexical scope`-dan danışanda `closure` mövzusuna girmək olar. Yaxşı, gerisi sonra! :) 97 | 98 | #### İkinci hissədə scope və call stack əlaqəsini detallı öyrənəcəyik. 99 | 100 | 101 | ### Unutmayın ki, 102 | 103 | Unutmayın ki, yazılan izahlar hər zaman 100% bütöv deyil. Yəni izahlar doğrudur, yazılanlar baş verir amma daha dərində hərşey çox daha mürəkkəb işləyir. İzahlar, iş prinsipini başa düşməyimiz üçündür. 104 | 105 | #### Mənbələr 106 | 107 | - [Scope](https://developer.mozilla.org/en-US/docs/Glossary/Scope) 108 | - [Hoisting](https://developer.mozilla.org/en-US/docs/Glossary/Hoisting) 109 | - [Lexical Scope in JavaScript](https://www.freecodecamp.org/news/javascript-lexical-scope-tutorial/) 110 | - [Современный JavaScript](https://www.udemy.com/course/javascript-zero-to-junior-developer/) 111 | - [JavaScript Advanced](https://www.udemy.com/course/javascript-advance/) --------------------------------------------------------------------------------