Skip to content

KOTOEWai/JavaScripts

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

42 Commits
 
 

Repository files navigation

🚀 My JavaScript Journey

JavaScript ရဲ့ အခြေခံကနေ Advanced concepts တွေအထိ စနစ်တကျ လေ့လာထားတဲ့ Practice Repository ဖြစ်ပါတယ်။


📑 Table of Contents


🔗 Useful Links


JavaScript Execution Model

image

Js Engine

JavaScript Engine ဆိုတာ JavaScript code တွေကို Machine Code (သို့) Bytecode အဖြစ် ပြောင်းပြီး execute လုပ်ပေးတဲ့ software program တစ်ခုဖြစ်ပါတယ်။

  • Google Chrome, Edge → V8 Engine

  • Firefox → SpiderMonkey

  • Safari → JavaScriptCore (Nitro)

  • Node.js → V8 Engine ကိုပဲသုံးတယ်


JS Engine ရဲ့ အဓိက အစိတ်အပိုင်းများ

    1. Memory Heap
    1. Call Stack

 Memory Heap

JavaScript Engine ထဲက Memory Heap ဆိုတာ variable တွေ၊ objects တွေနဲ့
 data တွေကို သိမ်းဆည်းထားတဲ့ "ဂိုဒေါင်" တစ်ခုလိုပါပဲ။

Memory Heap ရဲ့ အဓိက အချက်များ

၁။ Unstructured Memory (ပုံသေ သတ်မှတ်မထားသော နေရာ)

Call Stack လိုမျိုး အစီအစဉ်တကျ (LIFO) သိမ်းတာမျိုး မဟုတ်ဘဲ၊ 
Heap ကတော့ ကြီးမားတဲ့ memory ဧရိယာကြီးတစ်ခုပါ။ ပုံထဲမှာလည်း data တွေကို
နေရာအနှံ့ ကြဲပြန့်ပြီး သိမ်းထားတာကို တွေ့နိုင်ပါတယ်။

၂။ ဘာတွေကို သိမ်းသလဲ?

Objects & Arrays: JavaScript မှာရှိတဲ့ reference types တွေ 
(ဥပမာ- {name: "Mg Mg"}, [1, 2, 3]) ကို ဒီမှာ သိမ်းပါတယ်။

Functions: Function definition တွေကိုလည်း memory heap ထဲမှာပဲ သိမ်းဆည်းပါတယ်။

Large Data: Stack ထဲမှာ သိမ်းဖို့ အရွယ်အစား ကြီးမားလွန်းတဲ့ data တွေကို
 ဒီနေရာမှာ နေရာချ (Allocate) ပေးပါတယ်။

၃။ Allocation vs Garbage Collection

Memory Allocation: Variable အသစ်တစ်ခု ဆောက်လိုက်တိုင်း Engine က Heap ထဲမှာ 
နေရာအလွတ်တစ်ခု ရှာပြီး သိမ်းပေးပါတယ်။

Garbage Collection: JavaScript မှာ Memory ကို ကိုယ်တိုင် ဖျက်ပေးစရာ မလိုပါဘူး။ 
Engine ထဲမှာ Garbage Collector ဆိုတာ ပါပါတယ်။
သူက Heap ထဲကို အမြဲစစ်ဆေးပြီး ဘယ် variable ကိုမှ အသုံးမပြုတော့ဘူး
(Reference မရှိတော့ဘူး) ဆိုရင် အဲဒီ memory ကို အလိုအလျောက် ပြန်သိမ်းသွားပါတယ်။


Call Stack နဲ့ ဘယ်လို ချိတ်ဆက်သလဲ?

ဒီအချက်က အရေးကြီးပါတယ်။

Object တစ်ခုကို Heap ထဲမှာ သိမ်းလိုက်တဲ့အခါ သူ့ရဲ့ 
Memory Address (Reference) လေးတစ်ခု ရလာပါတယ်။

အဲဒီ Address လေးကိုမှ Call Stack ထဲမှာရှိတဲ့ variable ထဲကို ထည့်သိမ်းလိုက်တာပါ။

ဥပမာ: const user = { name: "Aung Aung" }; လို့ ရေးရင်:

{ name: "Aung Aung" } ဆိုတဲ့ object ကြီးက Heap ထဲ ရောက်သွားမယ်။

user ဆိုတဲ့ variable နာမည်နဲ့ အဲဒီ data ရှိရာနေရာကို ညွှန်ပြတဲ့ Memory Address (Reference)လေးကတော့ Call Stack ထဲမှာ ရှိနေပါမယ်။

Memory Heap ထဲမှာ data တွေ အရမ်းများလာပြီး Garbage Collector ကလည်း
မဖျက်ပေးနိုင်တဲ့အခါ Memory Leak (စက်လေးသွားတာမျိုး) ဖြစ်တတ်ပါတယ်။

Call Stack

Call Stack ဆိုတာ JavaScript Engine က လက်ရှိ ဘယ် function တွေကို လုပ်ဆောင်နေသလဲ၊ 
ဘယ် function ထဲမှာ ရောက်နေသလဲဆိုတာကို ခြေရာခံတဲ့ ယန္တရားတစ်ခု ဖြစ်ပါတယ်။

သူ့ကို ရိုးရိုးရှင်းရှင်း ပြောရရင် "အလုပ်စာရင်းမှတ်တဲ့ စာအုပ်" လိုမျိုးဖြစ်ပြီး 

အောက်ပါ အချက်တွေက သူ့ရဲ့ အဓိက သဘောတရားတွေပါပဲ-

၁။ LIFO (Last In, First Out)

Call Stack ဟာ LIFO စနစ်နဲ့ အလုပ်လုပ်ပါတယ်။ 

ပန်းကန်ပြားတွေကို တစ်ချပ်ပေါ်တစ်ချပ် ဆင့်တင်ထားသလိုမျိုးပါပဲ။

Push: Function တစ်ခုကို ခေါ်လိုက်တဲ့အခါ Stack ရဲ့ အပေါ်ဆုံးကို ရောက်လာပါတယ်။

Pop: Function ထဲက အလုပ်တွေ ပြီးသွားတဲ့အခါ (Return ပြန်တဲ့အခါ) အပေါ်ဆုံးကနေ ပြန်ထွက်သွားပါတယ်။

၂။ Single Call Stack

JavaScript က Single-threaded ဖြစ်တဲ့အတွက် Call Stack တစ်ခုပဲ ရှိပါတယ်။
 ဒါကြောင့် သူက တစ်ကြိမ်မှာ အလုပ်တစ်ခုတည်းကိုပဲ အာရုံစိုက်လုပ်နိုင်ပါတယ်။ 
 အပေါ်က function မပြီးမချင်း အောက်က function ဆီကို မသွားပါဘူး။

၃။ အလုပ်လုပ်ပုံ ဥပမာ


function greet() {
  sayHi();
  console.log("Greet done");
}

function sayHi() {
  console.log("Hi!");
}

greet();


greet() ကို ခေါ်လိုက်ရင် Stack ထဲကို greet ရောက်လာပါတယ်။

greet ထဲမှာမှ sayHi() ကို ထပ်ခေါ်တဲ့အတွက် Stack ရဲ့ အပေါ်ဆုံးကို sayHi ထပ်ရောက်လာပါတယ်။

sayHi အလုပ်ပြီးသွားတဲ့အခါ Stack ထဲကနေ sayHi ထွက်သွားပါတယ်။

နောက်ဆုံးမှာ greet အလုပ်ပြီးလို့ Stack ထဲကနေ greet ထွက်သွားပြီး Stack က ပြန်လွတ် (Empty) သွားပါတယ်။

၄။ Stack Overflow (Error)

Function တစ်ခုကနေ နောက်ထပ် function တစ်ခုကို အဆုံးမရှိ (Infinite) ခေါ်နေမယ်ဆိုရင်
 Stack ထဲမှာ နေရာမဆန့်တော့ဘဲ ပြည့်လျှံသွားတတ်ပါတယ်။ ဒါကို Stack Overflow လို့ ခေါ်ပါတယ်။

Call Stack နဲ့ Event Loop
ပုံထဲမှာ မြင်ရတဲ့အတိုင်း Call Stack ထဲက အလုပ်တွေ အကုန်လုံး ပြီးသွားမှသာ 
Event Loop က Callback Queue ထဲမှာ စောင့်နေတဲ့ အလုပ်တွေကို Stack ထဲကို ပို့ပေးတာ ဖြစ်ပါတယ်။

Web APIs

Web APIs ဆိုတာ Browser (Web Runtime Environment) ကနေ ထောက်ပံ့ပေးထားတဲ့ 
အပိုထည့်ပေးထားတဲ့ Features  ဖြစ်ပါတယ်။

JavaScript က single-threaded ဖြစ်ပေမဲ့ နောက်ကွယ်မှာ အလုပ်တွေအများကြီးကို တစ်ပြိုင်နက်
လုပ်ဆောင်နိုင်နေတာဟာ ဒီ Web APIs တွေကြောင့် ဖြစ်ပါတယ်။

Web APIs ရဲ့ အဓိက တာဝန်များ

ပုံထဲမှာ ပြထားတဲ့အတိုင်း Web APIs တွေဟာ Engine ရဲ့ အပြင်ဘက်မှာ သီးသန့် အလုပ်လုပ်ကြတာပါ။

DOM (Document Object Model): JavaScript ကနေ HTML element တွေကို ရှာတာ၊ အရောင်ပြောင်းတာ၊ 
စာသားအသစ် ထည့်တာတွေကို လုပ်ဆောင်ပေးပါတယ်။

Timer (setTimeout/setInterval): သတ်မှတ်ထားတဲ့ အချိန်တစ်ခုအထိ စောင့်ဆိုင်းပေးတဲ့ အလုပ်ကို 
လုပ်ဆောင်ပေးပါတယ်။

Fetch APIs (Network Requests): Server ဆီကနေ data တွေ လှမ်းတောင်းတဲ့အခါ Browser ရဲ့ 
Network thread ကို သုံးပြီး အလုပ်လုပ်ပေးပါတယ်။

Other APIs: ပုံထဲမှာ ... လို့ ပြထားတဲ့အထဲမှာ Geolocation (တည်နေရာကြည့်ခြင်း)၊ 
Local Storage နဲ့ Canvas လိုမျိုး APIs တွေလည်း ပါဝင်ပါတယ်။

Web APIs က ဘယ်လို အလုပ်လုပ်သလဲ?

၁။ Request: Call Stack ကနေ setTimeout ဒါမှမဟုတ် fetch လိုမျိုး function ကို ခေါ်လိုက်တဲ့အခါ 
JS Engine က အဲဒီအလုပ်ကို Web APIs ဆီကို လွှဲပေးလိုက်ပါတယ်။

၂။ Offloading: Web APIs က အဲဒီအလုပ်ကို Browser ရဲ့ အခြား thread တွေ (ဥပမာ Network thread 
သို့မဟုတ် Timer thread) ကို သုံးပြီး နောက်ကွယ်မှာ သီးသန့် လုပ်ဆောင်ပါတယ်။

၃။ Callback: အလုပ်ပြီးသွားတဲ့အခါ (ဥပမာ Timer ပြည့်သွားတဲ့အခါ) Web API က အဲဒီအလုပ်နဲ့ သက်ဆိုင်တဲ့
Callback function ကို Callback Queue ထဲကို ပို့ပေးလိုက်ပါတယ်။

ဘာကြောင့် အရေးကြီးတာလဲ?

Web APIs မရှိဘူးဆိုရင် JavaScript ဟာ အရမ်း "နှေး" တဲ့ ဘာသာစကား ဖြစ်သွားပါလိမ့်မယ်။
ဥပမာ- Server ကနေ data လာတာကို စောင့်နေတဲ့အချိန်မှာ Web API မရှိရင် Browser ကြီး တစ်ခုလုံး 
ဘာမှလုပ်လို့မရဘဲ "Hang" နေမှာပါ။

အခုတော့ Web APIs က နောက်ကွယ်မှာ အလုပ်လုပ်ပေးနေလို့ ကျနော်တို့ Browser မှာ UI တွေကို ဆက်ပြီး
 အသုံးပြုနိုင်နေတာ ဖြစ်ပါတယ်။

Event Loop

Event Loop ဆိုတာ JavaScript Runtime ရဲ့ "စပယ်ယာ" သို့မဟုတ် "ယာဉ်ထိန်းရဲ" လိုမျိုး အဓိကကျတဲ့
အစိတ်အပိုင်းဖြစ်ပါတယ်။ သူက Call Stack နဲ့ Callback Queue တို့ကြားမှာ အလုပ်တွေကို ဘယ်အချိန်မှာ
လုပ်ဆောင်ရမလဲဆိုတာကို အမြဲတမ်း စီစဉ်ပေးနေတာပါ။

ပုံထဲက မြှားလေးကို ကြည့်ရင် Event Loop က အလုပ်တွေ လှည့်ပတ်နေပုံကို မြင်နိုင်ပါတယ်။

Event Loop ရဲ့ အလုပ်လုပ်ပုံ အဆင့်ဆင့်

Event Loop က အောက်ပါ အဆင့် ၃ ဆင့်ကို အမြဲတမ်း ထပ်ခါတလဲလဲ (Loop) ပတ်ပြီး လုပ်ဆောင်နေပါတယ်-

၁။ Call Stack ကို စစ်ဆေးခြင်း
Event Loop က Call Stack ထဲမှာ လက်ရှိ လုပ်နေတဲ့ code တွေ ရှိသေးလားဆိုတာကို အရင်ကြည့်ပါတယ်။
 အကယ်၍ Stack ထဲမှာ function တစ်ခုခု အလုပ်လုပ်နေတုန်းဆိုရင် သူက ဘာမှ ထပ်မလုပ်ဘဲ စောင့်နေပါတယ်။

၂။ Callback Queue ကို ကြည့်ခြင်း
Call Stack ထဲမှာ ဘာအလုပ်မှ မရှိတော့ဘူး (လွတ်သွားပြီ) ဆိုတာနဲ့ Event Loop က Callback Queue ဘက်ကို
လှည့်ကြည့်ပါတယ်။ Queue ထဲမှာ Web APIs ဆီကနေ ပြီးစီးလို့ ရောက်လာတဲ့ callback အလုပ်တွေ 
(ဥပမာ- click, timer, data) ရှိနေသလားလို့ စစ်ပါတယ်။

၃။ အလုပ်ကို လွှဲပြောင်းပေးခြင်း (The Push)
Queue ထဲမှာ အလုပ်ရှိနေရင် Event Loop က အဲဒီထဲက ပထမဆုံးအလုပ်ကို ယူပြီး Call Stack ထဲကို 
တွန်းတင် (Push) ပေးလိုက်ပါတယ်။ အဲဒီအခါမှသာ အဲဒီ callback function က တကယ် အလုပ်လုပ်တာဖြစ်ပါတယ်။

ဘာကြောင့် Event Loop က အရေးကြီးတာလဲ?

JavaScript က Single-threaded ဖြစ်ပေမဲ့ "မထစ်" ဘဲ အလုပ်လုပ်နိုင်တာဟာ ဒီ Event Loop ကြောင့်ပါ။

Non-blocking: setTimeout သို့မဟုတ် fetch လိုမျိုး ကြာမယ့်အလုပ်တွေကို Web APIs ဆီ လွှဲပေးထားနိုင်လို့ UI က 
ပုံမှန်အတိုင်း အလုပ်လုပ်နေနိုင်တာပါ။

Concurrency: အလုပ်တွေကို တစ်ပြိုင်နက် လုပ်နေသလိုမျိုး ခံစားရစေပါတယ်။ တကယ်တော့ နောက်ကွယ်မှာ 
Web APIs တွေက အလုပ်လုပ်ပေးနေပြီး Event Loop က အဖြေတွေကို အစီအစဉ်တကျ ပြန်စီပေးနေတာ ဖြစ်ပါတယ်။

Callback Queue

Callback Queue (သို့မဟုတ် Task Queue) ဆိုတာ Web APIs တွေဆီကနေ အလုပ်ပြီးစီးလို့ 
ပြန်လာတဲ့ function လေးတွေ Call Stack ထဲကို ပြန်ဝင်ဖို့အတွက် စောင့်ဆိုင်းရတဲ့ "တန်းစီဇယား" နေရာဖြစ်ပါတယ်။

ပုံထဲက JS Runtime Environment ရဲ့ ညာဘက်အောက်ခြေမှာ click, timer, data စတဲ့ 
အလုပ်လေးတွေ တန်းစီနေတဲ့ နေရာပဲ ဖြစ်ပါတယ်။

၁။ Callback Queue ထဲကို ဘယ်လိုရောက်လာသလဲ?
အလုပ်တစ်ခုက Callback Queue ထဲကို တိုက်ရိုက်မရောက်ပါဘူး။ အဆင့်ဆင့် ဖြတ်သန်းရပါတယ်:

Web APIs ကနေ တဆင့်လာခြင်း: ဥပမာ- setTimeout ရဲ့ timer ပြည့်သွားတဲ့အခါ သို့မဟုတ် fetch ကနေ 
data ရလာတဲ့အခါ အဲဒီအလုပ်နဲ့ သက်ဆိုင်တဲ့ callback function ကို Web API က Queue ထဲကို ပို့ပေးလိုက်တာပါ။

Events များ: User က ခလုတ်တစ်ခုကို နှိပ်လိုက်ရင် (click) အဲဒီ click event အတွက် ရေးထားတဲ့ function က 
Queue ထဲမှာ လာပြီး တန်းစီပါတယ်။

၂။ FIFO (First In, First Out) စနစ်
Callback Queue ဟာ FIFO စနစ်နဲ့ အလုပ်လုပ်ပါတယ်။ မှတ်တိုင်မှာ လူတွေ တန်းစီသလိုမျိုး 
အရင်ရောက်တဲ့ အလုပ်က အရင်ဆုံး ပြန်ထွက်ခွင့် ရပါတယ်။ Call Stack ရဲ့ LIFO စနစ်နဲ့ ဆန့်ကျင်ဘက်ပါ။

၃။ Event Loop နဲ့ ချိတ်ဆက်ပုံ
Callback Queue ထဲမှာ အလုပ်တွေ ဘယ်လောက်ပဲ ရှိနေပါစေ၊ သူတို့က Call Stack ထဲကို တန်းပြီး ဝင်လို့မရပါဘူး။

Event Loop က Call Stack ကို အမြဲကြည့်နေပြီး Stack လုံးဝ အားသွားပြီဆိုမှ Queue ထဲက အလုပ်တွေကို 
တစ်ခုချင်းစီ Stack ထဲကို ပို့ပေးတာဖြစ်ပါတယ်။

Callback Queue အမျိုးအစားများ (The Priority)
တကယ်တော့ Browser ထဲမှာ Queue က တစ်ခုတည်း မဟုတ်ပါဘူး။ ဦးစားပေးအဆင့် (Priority) ကွာခြားမှု ရှိပါတယ်:

Microtask Queue (Promises): Promise.then() ဒါမှမဟုတ် async/await တွေအတွက်ပါ။ သူက ဦးစားပေး အမြင့်ဆုံးပါ။

Callback Queue (Macrotask): setTimeout, setInterval နဲ့ DOM events တွေအတွက်ပါ။

ဥပမာ: Timer အလုပ်နဲ့ Promise အလုပ် နှစ်ခုစလုံး Queue ထဲမှာ တန်းစီနေရင် Event Loop က Promise အလုပ်
 (Microtask) ကို အရင်ယူပြီးမှ Timer အလုပ်ကို လုပ်ဆောင်ပေးမှာ ဖြစ်ပါတယ်။

LexicalStructure

JavaScript's lexical structure describes the basic building blocks of the language — the rules for writing code, forming tokens, naming variables, writing comments, and more. This document explains each part clearly.


1. What is Lexical Structure?

JavaScript ရဲ့ Lexical Structure ဆိုတာ အခြေခံကျတဲ့ စည်းမျဉ်းတွေ (Grammar Rules) ဖြစ်ပါတယ်။ Programming language တစ်ခုမှာ စာလုံးတွေကို ဘယ်လိုပေါင်းရမယ်၊
ဘယ်လိုရေးရမယ်ဆိုတဲ့ အခြေခံ "သဒ္ဒါ" လို့ ပြောလို့ရပါတယ်။

၁။ Case Sensitivity (အကြီးအသေး ခွဲခြားခြင်း)

JavaScript ဟာ Case-sensitive ဖြစ်ပါတယ်။ ဆိုလိုတာက စာလုံးအကြီးအသေး ကွာခြားရင် အဓိပ္ပာယ် မတူတော့ပါဘူး။

let name = "Aung Aung";
let Name = "Su Su";
let NAME = "Kyaw Kyaw";
// ဒီသုံးခုလုံးဟာ variable သီးခြားစီ ဖြစ်ပါတယ်။

၂။ Whitespace and Line Breaks
JavaScript မှာ ကွက်လပ် (Space) တွေနဲ့ စာကြောင်းဆင်းတာ (Line break) တွေကို များသောအားဖြင့် လျစ်လျူရှုပါတယ်။ ဒါကြောင့် ကုဒ်တွေကို ဖတ်ရလွယ်အောင် စီရေးလို့ရပါတယ်။

// အတူတူပါပဲ
let x=5;
let x  =   5;

၃။ Literals (တိုက်ရိုက်တန်ဖိုးများ)
Literals ဆိုတာ ကုဒ်ထဲမှာ တိုက်ရိုက်ရေးသားလိုက်တဲ့ data တန်ဖိုးတွေ ဖြစ်ပါတယ်။

123 (Number literal)

"Hello" (String literal)

true (Boolean literal)

{a: 1} (Object literal)

၄။ Identifiers (အမည်ပေးခြင်း စည်းမျဉ်း)

Variables တွေ၊ Functions တွေကို နာမည်ပေးတဲ့အခါ လိုက်နာရမယ့် စည်းမျဉ်းတွေပါ။

အစစာလုံးကို အက္ခရာ (letter)၊ underscore (_) ဒါမှမဟုတ် dollar sign ($) နဲ့ စရပါမယ်။

ကိန်းဂဏန်း (0-9) နဲ့ စလို့ မရပါ။

Reserved Keywords (ဥပမာ- if, while, return) တွေကို သုံးလို့မရပါ။

၆။ Semicolons (;)
JavaScript မှာ statement တစ်ခုပြီးတိုင်း semicolon ထည့်လေ့ရှိပါတယ်။ အခုခေတ်မှာ JavaScript က အလိုအလျောက် ထည့်ပေးတဲ့စနစ် (Automatic Semicolon Insertion)
ပါဝင်ပေမဲ့ အမှားနည်းအောင် ကိုယ်တိုင်ထည့်တာက အကောင်းဆုံး အလေ့အကျင့်ပါ။

၇။ Unicode
JavaScript ကုဒ်တွေကို Unicode character set နဲ့ ရေးသားထားတာဖြစ်လို့ variable name တွေမှာ မြန်မာစာအပါအဝင် ဘာသာစကားအမျိုးမျိုးကို သုံးလို့ရပါတယ်။

let နာမည် = "မောင်မောင်";
console.log(နာမည်); // Output: မောင်မောင်



Lexical structure defines how JavaScript source code is read and broken into tokens. It includes:

  • Character set
  • Case sensitivity
  • Whitespace
  • Line terminators
  • Comments
  • Literals
  • Identifiers & keywords
  • Operators & punctuators

2. Character Set

JavaScript uses the Unicode character set.

  • This means it supports characters from almost all languages.
  • Variable names can include Unicode letters — even emojis (not recommended in production).
let မြန်မာ = "Hello";
let 🚀 = 10;

3. Case Sensitivity

JavaScript is case-sensitive.

let name = "A";
let Name = "B"; // different variable

Keywords are also case-sensitive.


4. Whitespace

Whitespace includes spaces, tabs, and newlines.

  • JavaScript generally ignores whitespace, except in specific cases.

Example:

let x = 10;
let  y    =    20;

Both are valid.


5. Line Terminators

Line terminators are characters such as:

  • \n (newline)
  • \r (carriage return)

They can affect automatic semicolon insertion (ASI), so be careful.

Example (dangerous):

return
  5; // returns undefined due to ASI

6. Comments

Single-line comment

// This is a comment

Multi-line comment

/*
  This is a multi-line comment
*/

Note: Comments do not nest.


7. Identifiers

Identifiers are names for:

  • variables
  • functions
  • classes

Rules:

  • Must start with: letter, _, $
  • After first char: digits are allowed.

Valid:

let _value;
let $item;
let user123;

Invalid:

let 1user; // cannot start with digit

8. Keywords

These words have special meaning and cannot be used as identifiers. Examples:

break, case, class, const, continue, debugger, default,
delete, do, else, export, extends, finally, for, function,
if, import, in, instanceof, let, new, return, super,
switch, this, throw, try, typeof, var, void, while, with, yield

9. Literals

Literals are fixed values appearing directly in code.

Number literals

let a = 10;
let b = 3.14;
let hex = 0xFF;
let binary = 0b1010;

String literals

let s1 = "hello";
let s2 = 'world';
let s3 = `template literal`;

Boolean literals

true, false

Null & Undefined

null;
undefined;

10. Operators & Punctuators

These include:

  • + - * / %
  • = += -= *=
  • == === != !==
  • { } [ ] ( )
  • , ; . ? :

JavaScript treats these as tokens during lexical scanning.


11. Automatic Semicolon Insertion (ASI)

JavaScript automatically inserts semicolons in some cases. This can cause unexpected behavior.

Bad:

let x = 5
let y = 10
(x + y).toString() // treated as function call

Recommended:

  • Always use semicolons or
  • Follow JS formatting rules carefully.

12. Escape Sequences

Used inside strings:

  • \n → newline
  • \t → tab
  • \" → double-quote
  • \\ → backslash

Example:

let text = "Hello\nWorld";

13. Unicode Escapes

Identifiers may include Unicode escapes:

let \u006Eame = "John"; // same as "name"

String Unicode:

"\u{1F600}"; // 😀

Summary

JavaScript lexical structure defines how source code is read, including:

  • Unicode support
  • Case sensitivity
  • Whitespace handling
  • Comments
  • Identifiers & keywords
  • Literals
  • Operators & punctuation
  • ASI behavior

Understanding these rules helps you write cleaner and more predictable JavaScript.


Expressions

JavaScript expressions are pieces of code that produce a value. They are the building blocks of statements and logic in JavaScript.

JavaScript မှာ Expression ဆိုတာ တန်ဖိုးတစ်ခု (Value) ထွက်လာအောင် လုပ်ပေးတဲ့ Code အစိတ်အပိုင်းလေးတွေကို ခေါ်တာပါ။ လွယ်လွယ်ပြောရရင် တွက်ချက်မှုတစ်ခု လုပ်လိုက်လို့ဖြစ်စေ၊ ခေါ်ယူလိုက်လို့ဖြစ်စေ အဖြေတစ်ခုခု ထွက်လာရင် အဲဒါ Expression ပါပဲ။


1. What Is an Expression?

JavaScript မှာ Expression ဆိုတာ တန်ဖိုးတစ်ခုခု (Value) ထွက်လာအောင် တွက်ချက်ပေးတဲ့ Code အပိုင်းအစကို ခေါ်တာပါ။

အရိုးရှင်းဆုံး မှတ်သားချင်ရင် - "တစ်ခုခုကို တွက်ချက်ပြီး အဖြေ (Value) တစ်ခု ပြန်ပေးရင် အဲဒါ Expression ပဲ" လို့ မှတ်နိုင်ပါတယ်။

၁။ Expression အမျိုးအစားများ

JavaScript မှာ Expression အမျိုးအစား အများကြီးရှိပါတယ်။

Arithmetic Expressions: ကိန်းဂဏန်း တွက်ချက်မှုများ။

5 + 5 (အဖြေ 10 ထွက်သည်)

10 * 2 (အဖြေ 20 ထွက်သည်)

String Expressions: စာသားများ ပေါင်းစပ်ခြင်း။

"Hello " + "World" (အဖြေ "Hello World" ထွက်သည်)

Logical Expressions: ဟုတ်/မဟုတ် စစ်ဆေးခြင်း။

10 > 5 (အဖြေ true ထွက်သည်)

Primary Expressions: အခြေခံ တန်ဖိုးများ။

true, 22, "Mg Mg" (၎င်းတို့ကိုယ်တိုင်သည်လည်း expression များ ဖြစ်သည်)

၂။ Expression vs Statement (အရေးကြီးသော ကွာခြားချက်)

Programming မှာ Expression နဲ့ Statement ကို မှားတတ်ကြပါတယ်။

Expression: တန်ဖိုးတစ်ခုကို ပြန်ပေးတယ်။ ဥပမာ- 2 + 2

Statement: အလုပ်တစ်ခုကို လုပ်ဆောင်တယ်။ ဥပမာ- let x = 10; (ဒါက variable ကြေညာတဲ့ statement ဖြစ်ပြီး ဘာတန်ဖိုးမှ ပြန်မပေးပါဘူး)

၃။ React မှာ Expression ကို ဘယ်လိုသုံးသလဲ?

React (JSX) ရေးတဲ့အခါ JavaScript Expression တွေကို Curly Braces { } ထဲမှာ ထည့်ရေးရပါတယ်။



function Welcome() {
  const name = "Aung Aung";
  
  return (
    <div>
      {/* ဤသည်မှာ Expression ဖြစ်သည် */}
      <h1>မင်္ဂလာပါ {name}</h1> 
      
      {/* ဤသည်မှာလည်း Expression ဖြစ်သည် */}
      <p>၅ ပေါင်း ၅ သည် {5 + 5} ဖြစ်သည်။</p>
    </div>
  );
}

၄။ Ternary Operator (Expression အဖြစ်သုံးသော If-Else)
React မှာ if-else statement ကို JSX ထဲမှာ ရေးလို့မရပါဘူး (ဘာလို့လဲဆိုတော့ သူက statement ဖြစ်လို့ပါ)။ ဒါကြောင့် အဖြေပြန်ပေးတဲ့ Ternary Expression ကို သုံးရပါတယ်။

JavaScript

{isLoggedIn ? "Welcome Back!" : "Please Log In"}
အနှစ်ချုပ်
Expression သည် တန်ဖိုး (Value) တစ်ခုကို ထုတ်ပေးသည်။

React ၏ JSX ထဲတွင် Expression များကိုသာ { } ဖြင့် သုံးနိုင်သည်။

An expression is any valid unit of code that evaluates to a value.

Examples:

5          // number expression
"Hi"       // string expression
x + y      // arithmetic expression
sayHello() // function call expression

2. Primary Expressions

These are the simplest expressions that represent literal values or keywords.

Examples:

42
true
"hello"
null
undefined
this

Identifier Reference

name;
count;

3. Object & Array Initializer Expressions

Object Literal

let user = {
  name: "Aye",
  age: 20,
};

Array Literal

let numbers = [1, 2, 3];

4. Arithmetic Expressions

Perform mathematical operations.

x + y
x - y
x * 2
x / 10
x % 3
x ** 2

5. String Expressions

Involves string concatenation or template literals.

"Hello" + " World"
`User: ${username}`

6. Logical Expressions

Use &&, ||, and !.

true && false
isLoggedIn || hasToken
!isAdmin

Logical operators return values, not booleans only.

"A" && "B"  // "B"
"A" || "B"  // "A"

7. Comparison Expressions

x > y
x < y
x >= y
x === y
x !== y

They return true or false.


8. Assignment Expressions

These assign values and return the assigned value.

x = 10
x += 5
x -= 2
x *= 3

Example:

let a;
console.log(a = 5); // prints 5

9. Function Call Expressions

Calling a function is an expression.

doSomething()
alert("Hi")
sum(10, 20)

Even methods:

user.getName()

10. Optional Chaining Expression

Safely access nested properties.

user?.address?.city

11. Member Access Expressions

Access properties:

Dot notation

user.name

Bracket notation

user["name"]

12. Conditional (Ternary) Expression

Short "if...else" that returns a value.

let status = age >= 18 ? "Adult" : "Child";

13. Arrow Function Expressions

Functions used as expressions.

const add = (a, b) => a + b;

Arrow function without body braces implicitly returns:

const double = x => x * 2;

14. Spread & Rest Expressions

Spread

let newArr = [...oldArr];

Rest

function sum(...nums) {
  return nums.reduce((a, b) => a + b);
}

15. Comma Operator Expression

Evaluates multiple expressions but returns the last one.

let x = (1, 2, 3); // x = 3

Rarely used.


16. new Expression

Used to create instances.

let date = new Date();
let user = new User("Aye");

17. typeof, void, and delete Expressions

typeof

typeof 123 // "number"

void

void 0 // undefined

delete

delete obj.key

18. Await Expression

Used in async functions.

let data = await fetch("/api");

19. Grouping Expressions

Control evaluation order.

(2 + 3) * 4

Summary

JavaScript expressions:

  • Always produce a value
  • Can be simple (like 5) or complex (like user?.profile?.name ?? "Unknown")
  • Form the core of JavaScript logic

Understanding expressions helps you write more powerful and flexible code.


DataTypes

JavaScript has a flexible and dynamic type system. Every value in JavaScript belongs to a data type, and understanding them is essential for writing clean, predictable code.


JavaScript မှာ Data Types ဆိုတာ ကွန်ပျူတာက ဒေတာတွေကို ဘယ်လိုအမျိုးအစားအဖြစ် မှတ်သားမလဲဆိုတဲ့ သတ်မှတ်ချက် ဖြစ်ပါတယ်။ 
JavaScript မှာ ဒေတာအမျိုးအစားတွေကို အဓိက အုပ်စုကြီး (၂) စု ခွဲထားပါတယ်။

၁။ Primitive Data Types (အခြေခံ အမျိုးအစားများ)
ဒါတွေက တန်ဖိုးတစ်ခုတည်းကိုပဲ သိမ်းဆည်းနိုင်ပြီး ပြောင်းလဲလို့မရတဲ့ (Immutable) အခြေခံအမျိုးအစား ၇ ခု ဖြစ်ပါတယ်။

String: စာသားများ။ (ဥပမာ- "Hello", 'Mingalarbar')

Number: ကိန်းဂဏန်းများ (Integer ရော Float ပါ ပါဝင်သည်)။ (ဥပမာ- 25, 3.14)

Boolean: ဟုတ်/မဟုတ်။ (true သို့မဟုတ် false)

Undefined: Variable တစ်ခုကို ကြေညာထားပြီး တန်ဖိုးမထည့်ရသေးတဲ့ အခြေအနေ။

Null: တမင်တကာ "ဘာမှမရှိဘူး" လို့ သတ်မှတ်ထားတဲ့ တန်ဖိုး (Empty value)။

Symbol: ထူးခြားပြီး တစ်ခုတည်းသော identifier အဖြစ် သုံးပါတယ်။ (ES6)

BigInt: အလွန်ကြီးမားတဲ့ ကိန်းဂဏန်းတွေ သိမ်းဖို့ သုံးပါတယ်။


၂။ Non-Primitive (Reference) Data Types

ဒါတွေကတော့ ရှုပ်ထွေးတဲ့ ဒေတာပုံစံတွေဖြစ်ပြီး တန်ဖိုးအများကြီးကို စုစည်းသိမ်းဆည်းနိုင်ပါတယ်။

1. Object: Key-value အတွဲလိုက် သိမ်းဆည်းတဲ့ ဒေတာပုံစံ။

const person = { name: "Aung Aung", age: 20 };


2. Array: စာရင်း (List) ပုံစံ သိမ်းဆည်းတာဖြစ်ပြီး တကယ်တော့ Object အမျိုးအစားထဲကပါပဲ။

const fruits = ["Apple", "Banana", "Orange"];


3. Function: အလုပ်လုပ်ဆောင်ချက်တွေကို သိမ်းဆည်းထားတဲ့ အမျိုးအစား။

၃။ Static vs Dynamic Typing

JavaScript ဟာ Dynamic Typed Language ဖြစ်ပါတယ်။ ဆိုလိုတာက Variable တစ်ခုကို ဘာ အမျိုးအစားလဲဆိုတာ ကြိုပြောစရာမလိုဘဲ ထည့်လိုက်တဲ့ တန်ဖိုးပေါ်မူတည်ပြီး အမျိုးအစားက အလိုအလျောက် ပြောင်းလဲသွားပါတယ်။

let x = 5;       // x က Number ဖြစ်သွားပြီ
x = "Hello";     // အခု x က String ဖြစ်သွားပြန်ပြီ

၄။ typeof Operator

Variable တစ်ခုက ဘာ Data Type လဲဆိုတာကို သိချင်ရင် typeof ကို သုံးပြီး စစ်ဆေးနိုင်ပါတယ်။

typeof 10;        // "number"
typeof "hi";     // "string"
typeof true;      // "boolean"
typeof undefined; // "undefined"
typeof null;      // "object" (bug)
typeof {};        // "object"
typeof [];        // "object"
typeof function(){}; // "function"


Primitive တွေက ရိုးရှင်းပြီး Memory ထဲမှာ တိုက်ရိုက်သိမ်းတယ်။

Reference (Objects) တွေက ရှုပ်ထွေးပြီး Memory ထဲမှာ Reference (လိပ်စာ) အနေနဲ့ သိမ်းတယ်။

1. Overview of Data Types

JavaScript has 8 main data types:

Primitive Data Types (7 types)

  1. Number
  2. String
  3. Boolean
  4. Undefined
  5. Null
  6. Symbol
  7. BigInt

Non‑Primitive Data Type (1 type)

  1. Object

2. Primitive Data Types

Primitive values:

  • are immutable
  • compared by value
  • stored directly in memory

2.1 Number

Represents both integers and floating‑point numbers.

let age = 18;
let price = 19.99;
let infinity = Infinity;
let notNumber = NaN;

JavaScript does not have separate types for int, float, double.


2.2 String

Represents text.

let name = "Aye";
let message = 'Hello';
let greeting = `Hi ${name}`; // template literal

2.3 Boolean

Represents logical values.

let isLoggedIn = true;
let hasToken = false;

Common Boolean operations:

true && false
true || false
!true

2.4 Undefined

A variable that has been declared but not assigned.

let x;
console.log(x); // undefined

2.5 Null

Represents an intentional absence of value.

let user = null;

Note:

typeof null; // "object" (JS historical bug)

2.6 Symbol (ES6)

Unique and immutable values, often used as object keys.

let id = Symbol("id");
let obj = {
  [id]: 123,
};

2.7 BigInt (ES2020)

Used for very large integers.

let big = 12345678901234567890n;
let sum = big + 10n;

BigInts cannot mix with normal numbers:

10 + 10n; // ❌ error

3. Non‑Primitive Data Type

3.1 Object

Objects store key‑value pairs.

let user = {
  name: "Aye",
  age: 20,
};

Objects include:

  • arrays
  • functions
  • dates
  • regex
  • maps
  • sets

Everything that is not primitive is an object.


4. Special Object Types

4.1 Array

Ordered list of values.

let arr = [1, 2, 3];

4.2 Function

Functions are objects with callable behavior.

function greet() {
  return "Hello";
}

4.3 Date

Represents date and time.

let now = new Date();

4.4 Map

Stores key‑value pairs with any key type.

let map = new Map();
map.set("name", "Aye");

4.5 Set

Stores unique values.

let set = new Set([1, 2, 2, 3]); // {1,2,3}

5. Dynamic Typing

JavaScript is dynamically typed, meaning variables can change type at runtime.

let x = 10;
x = "ten";

6. Type Checking

typeof operator

typeof 10;        // "number"
typeof "hi";     // "string"
typeof true;      // "boolean"
typeof undefined; // "undefined"
typeof null;      // "object" (bug)
typeof {};        // "object"
typeof [];        // "object"
typeof function(){}; // "function"

7. Difference Between Primitive & Object

Feature Primitive Object
Storage Value Reference
Mutable? No Yes
Compared by Value Reference
Examples 10, "hi", true {}, [], functions

Example:

let a = { x: 1 };
let b = { x: 1 };
a === b; // false (different references)

8. Type Conversion

Implicit Conversion (Coercion)

"5" - 1  // 4
"5" + 1  // "51"

Explicit Conversion

Number("5")
String(123)
Boolean(1)

Summary

JavaScript data types include:

  • 7 primitive types: Number, String, Boolean, Undefined, Null, Symbol, BigInt
  • 1 non‑primitive type: Object
  • JavaScript is dynamically typed
  • Primitive values are simple and immutable
  • Objects are complex and mutable

Understanding data types helps prevent bugs and write cleaner, more predictable code.


Variables

Variables are one of the most fundamental parts of JavaScript. They allow you to store, update, and reuse values inside your programs.


1. What Is a Variable?

A variable is a named container for storing data.

let message = "Hello World";

2. Variable Declaration Keywords

JavaScript has 3 ways to declare variables:

var

let

const

Each behaves differently.


3. let

Introduced in ES6, used for block-scoped variables.

let age = 20;
age = 21; // reassign allowed

Features:

  • Block scoped {}
  • Can be reassigned
  • Cannot be redeclared in the same scope

Example:

if (true) {
  let x = 10;
}
console.log(x); // ❌ Error (x is block-scoped)

4. const

Also block-scoped, but cannot be reassigned.

const PI = 3.14;
// PI = 3.15; ❌ Error

Important:

const does not make objects immutable.

const user = { name: "Aye" };
user.name = "Ko"; // ✔ allowed

You cannot reassign a new object:

user = {}; // ❌ not allowed

5. var

Function-scoped and older keyword.

var name = "Aye";

Problems with var:

  • Not block scoped
  • Can be redeclared
  • Causes unexpected behavior due to hoisting

Example:

if (true) {
  var x = 10;
}
console.log(x); // ✔ 10 (var ignores block scope)

Use let or const instead.


6. Scope

Scope determines where a variable can be used.

Types:

  1. Block Scope (let, const)
  2. Function Scope (var)
  3. Global Scope

Example:

let globalVar = "I am global"; // Global scope

function exampleFunction() {
  var functionVar = "I am function-scoped"; // Function scope (var)

  if (true) {
    let blockVar = "I am block-scoped"; // Block scope (let)
    console.log(blockVar); // Accessible here
  }

  // console.log(blockVar); // Error: blockVar is not defined here
  console.log(functionVar); // Accessible here
}

exampleFunction();
console.log(globalVar); // Accessible here
// console.log(functionVar); // Error: functionVar is not defined here

7. Hoisting

Hoisting ဆိုတာ ➡️ JavaScript engine က code run မလုပ်ခင် ➡️ variable declarations (var, let, const) ➡️ function declarations တွေကို memory ထဲကို အရင် ထားသွားတဲ့ behavior ကို ဆိုလိုတာပါ။

var is hoisted with undefined value:

console.log(x); // undefined
var x = 10;

let and const are hoisted but in Temporal Dead Zone (TDZ):

console.log(y); // ❌ Error
let y = 10;

8. Initialization vs Declaration

let x;       // declaration
x = 5;       // initialization

let y = 10;  // declared + initialized

9. Naming Variables

Variable names must follow rules.

Valid:

let name;
let _counter;
let $money;
let age2;

Invalid:

let 1age;   // cannot start with number
let @name;  // symbols not allowed

Best Practices:

  • Use camelCase → userName
  • Use descriptive names → totalPrice
  • Constants in ALL_CAPS → MAX_USERS

10. let vs const vs var

Feature var let const
Scope Function Block Block
Redeclare? ✔ Yes ❌ No ❌ No
Reassign? ✔ Yes ✔ Yes ❌ No
Hoisting Yes (undefined) TDZ TDZ

Recommended:

  • Use const by default
  • Use let when value will change
  • Avoid var

11. Global Variables

Variables declared outside functions.

let a = 10; // global

Global variables can cause bugs — use only when needed.


12. Reassignment Examples

let count = 1;
count = 2; // ✔ allowed

const PI = 3.14;
PI = 3.2; // ❌ not allowed

Summary

JavaScript variables:

  • Store values for reuse
  • Declared using var, let, or const
  • let & const are block-scoped
  • var is function-scoped and outdated
  • const prevents reassignment
  • Hoisting affects how variables behave

Understanding variables helps you control data flow and avoid bugs.


Operators

1. What Are Operators?

Operators are symbols that tell JavaScript to perform some action (calculations, comparisons, assignments, logic, etc.).

Example:

let x = 10 + 5;

Here:

  • = is an assignment operator
  • + is an arithmetic operator

2. Types of Operators

JavaScript has several categories of operators:

  1. Arithmetic Operators
  2. Assignment Operators
  3. Comparison Operators
  4. Logical Operators
  5. Unary Operators
  6. Ternary Operator
  7. String Operators
  8. Bitwise Operators
  9. Type Operators (typeof, instanceof)
  10. Optional Chaining & Nullish Coalescing Operators

3. Arithmetic Operators

Operator Name Example
+ Addition 5 + 27
- Subtraction 5 - 23
* Multiplication 5 * 210
/ Division 10 / 25
% Modulus (remainder) 5 % 21
** Exponentiation 2 ** 38
++ Increment x++
-- Decrement x--

Example:

let a = 10;
a++;
console.log(a); // 11

4. Assignment Operators

Operator Meaning Example
= Assign x = 10
+= Add and assign x += 5 (x = x + 5)
-= Subtract and assign x -= 5
*= Multiply and assign x *= 5
/= Divide and assign x /= 5
%= Modulus and assign x %= 5
**= Power and assign x **= 2

5. Comparison Operators

These return true or false.

Operator Meaning Example
== Equal (loose) 5 == "5" → true
=== Strict equal 5 === "5" → false
!= Not equal 5 != 3
!== Strict not equal 5 !== "5"
> Greater than 10 > 5
< Less than 5 < 10
>= Greater or equal 10 >= 10
<= Less or equal 5 <= 5

Example:

console.log(5 === "5"); // false

6. Logical Operators

| Operator | Meaning | Example                   |   
| -------- | ------- | ------------------------- | 
| `&&`     | AND     | `true && false`  `false` |    
| `||`     | OR      | `true || false``true`    |         
| `!`      | NOT     | `!true`  `false`         |      

Example:

let isLoggedIn = true;
let isAdmin = false;
console.log(isLoggedIn && isAdmin); // false

7. Unary Operators

Operator Meaning
typeof Returns data type
void Evaluates but returns undefined
delete Removes object property
+ Convert to number
- Convert to negative number

Example:

console.log(typeof 123); // "number"

8. Ternary Operator (Conditional Operator)

Shorthand for if/else.

condition ? valueIfTrue : valueIfFalse;

Example:

let age = 18;
let msg = age >= 18 ? "Adult" : "Minor";
console.log(msg);

9. String Operator

The + operator is used for string concatenation.

let name = "Toe" + "Wai";
console.log(name); // "ToeWai"

10. Nullish Coalescing Operator (??)

Returns the right-hand value when the left side is null or undefined.

let user;
console.log(user ?? "Guest"); // Guest

11. Optional Chaining Operator (?.)

Avoids errors when accessing properties of undefined or null.

let user = {};
console.log(user.address?.street); // undefined, no error

12. Bitwise Operators

Advanced topic — used for low-level operations.

| Operator | Meaning               |    
| -------- | --------------------- | 
| `&`      | AND                   |    
|  ||      | OR                    |  
| `^`      | XOR                   |    
| `~`      | NOT                   |    
| `<<`     | Left shift            |    
| `>>`     | Right shift           |    
| `>>>`    | Zero-fill right shift |    

13. Operator Precedence (Which Runs First?)

Example:

2 + 3 * 4; // 14 (because * runs before +)

Shortcut:

  • () parentheses highest
  • Then unary (!, typeof)
  • Then * / %
  • Then + -
  • Then comparisons
  • Then logical
  • Last: assignment

Conditions

A complete guide to how decisions are made in JavaScript — using if, else, switch, ternary, truthy/falsy, and more.


1. What Are Conditions?

Conditions allow JavaScript to make decisions based on true/false results.

Example:

let age = 18;
if (age >= 18) {
  console.log("You are an adult");
}

2. Types of Conditional Statements

JavaScript supports:

  1. if statement
  2. if...else statement
  3. else if chain
  4. switch statement
  5. Ternary operator (? :)
  6. && and || short‑circuit conditions
  7. Optional chaining (?.) with conditions

3. The if Statement

Runs code only when the condition is true.

if (condition) {
  // code
}

Example:

let score = 80;
if (score > 50) {
  console.log("Pass");
}

4. if...else Statement

Runs one block if true, another if false.

if (condition) {
  // true block
} else {
  // false block
}

Example:

let isOnline = false;
if (isOnline) {
  console.log("User is online");
} else {
  console.log("User is offline");
}

5. else if Chain

Checks multiple conditions one by one.

if (temperature > 30) {
  console.log("Hot");
} else if (temperature > 20) {
  console.log("Warm");
} else {
  console.log("Cold");
}

6. switch Statement

Used when checking one value against many possible cases.

switch (day) {
  case "Mon":
    console.log("Work day");
    break;
  case "Sat":
    console.log("holiday");
  case "Sun":
    console.log("Weekend");
    break;
  default:
    console.log("Unknown day");
}

Why use switch?

  • Cleaner when many else if conditions
  • Great for checking a single variable

7. Ternary Operator (? :)

Short version of if...else.

condition ? valueIfTrue : valueIfFalse;

Example:

let age = 18;
let message = age >= 18 ? "Adult" : "Minor";
console.log(message);

Best used for simple decisions.


8. Truthy and Falsy Values

JavaScript treats some values as true or false automatically.

Falsy values:

  • false
  • 0
  • "" (empty string)
  • null
  • undefined
  • NaN

Everything else is truthy.

Example:

if ("") console.log("This won't run");
if ("hello") console.log("This will run");

9. Logical Operators in Conditions

&& (AND)

Runs only if both conditions are true.

if (isLoggedIn && isAdmin) {
  console.log("Welcome Admin");
}

|| (OR)

Runs if at least one condition is true.

if (day === "Sat" || day === "Sun") {
  console.log("Weekend");
}

! (NOT)

Reverses a boolean.

if (!isOnline) {
  console.log("Offline");
}

10. Optional Chaining in Conditions (?.)

Avoids errors when checking nested properties.

if (user?.address?.city) {
  console.log("City found");
}

11. Combining Multiple Conditions

Example:

let age = 20;
let hasID = true;

if (age >= 18 && hasID) {
  console.log("You may enter");
}

12. Common Mistakes

Using = instead of == or ===

if (x = 5) { } // WRONG

This assigns, not compares.

Correct:

if (x === 5) { }

Forgetting break in switch

switch(x) {
  case 1:
    console.log("One");
  case 2:
    console.log("Two"); // Both run ❌
}

13. Summary

Use conditions to:

  • Make decisions
  • Control program flow
  • Validate data
  • React to user input

Tools for conditions:

  • if, else, else if
  • switch
  • Ternary operator
  • Logical operators
  • Truthy/falsy evaluation

Loops

A complete guide to loops in JavaScript — how to repeat actions, iterate data, and control flow efficiently.


1. What Are Loops?

Loops allow you to repeat code multiple times — automatically.

Example:

for (let i = 1; i <= 3; i++) {
  console.log(i);
}

Output:

1
2
3

2. Types of Loops in JavaScript

JavaScript supports several loop types:

  1. for loop

  2. while loop

  3. do...while loop

  4. for...of loop (iterate arrays, strings, etc.)

  5. for...in loop (iterate object keys)

  6. Array iteration methods (not exactly loops but commonly used)

    • forEach
    • map
    • filter
    • reduce

3. The for Loop

Most common and powerful loop.

Syntax:

for (initialization; condition; update) {
  // code
}

Example:

for (let i = 0; i < 5; i++) {
  console.log("Number:", i);
}

4. The while Loop

Runs as long as the condition is true.

let i = 0;
while (i < 3) {
  console.log(i);
  i++;
}

Use when you don't know how many times to loop.


5. The do...while Loop

Runs at least once, even if the condition is false.

let i = 5;
do {
  console.log(i);
  i++;
} while (i < 3);

6. The for...of Loop

Used for iterating iterables:

  • Arrays
  • Strings
  • Maps
  • Sets

Example:

let colors = ["red", "green", "blue"];
for (const c of colors) {
  console.log(c);
}

7. The for...in Loop

Used to iterate object keys.

let user = {
  name: "Toe",
  age: 18,
};

for (const key in user) {
  console.log(key, user[key]);
}

⚠️ Avoid using for...in for arrays.


8. Array Iteration Methods

These are not loops but often replace loops.

forEach (loop through each item)

[1, 2, 3].forEach(n => console.log(n));

map (returns new array)

let doubled = [1, 2, 3].map(n => n * 2);

filter (filters values)

let even = [1, 2, 3, 4].filter(n => n % 2 === 0);

reduce (accumulates values)

let sum = [1, 2, 3].reduce((a, b) => a + b, 0);

9. Loop Control: break and continue

break → stops the loop completely.

for (let i = 1; i <= 5; i++) {
  if (i === 3) break;
  console.log(i);
}

continue → skips current iteration.

for (let i = 1; i <= 5; i++) {
  if (i === 3) continue;
  console.log(i);
}

10. Infinite Loops (Be Careful!)

while (true) {
  console.log("This never stops");
}

Make sure your loop condition eventually becomes false.


11. Nested Loops

Loop inside a loop.

for (let i = 1; i <= 2; i++) {
  for (let j = 1; j <= 3; j++) {
    console.log(i, j);
  }
}

12. When to Use Which Loop?

Loop Type Best Use
for Known number of iterations
while Unknown number of iterations
do...while Run at least once
for...of Arrays, strings, iterables
for...in Object keys
forEach Simple iteration (no break)
map Transform array
filter Filter array
reduce Calculate a single value

13. Common Mistakes

❌ Forgetting to update the counter ❌ Creating infinite loops ❌ Using for...in for arrays ❌ Expecting break inside forEach (it does not work)


14. Summary

Loops help you:

  • Repeat actions
  • Work with collections
  • Automate repetitive tasks
  • Process arrays/objects

You now know:

  • for, while, do...while
  • for...of, for...in
  • Array iteration methods
  • break/continue

Functions

A complete guide to JavaScript functions — definitions, types, parameters, return values, arrow functions, scopes, closures, and more.


1. What Is a Function?

A function is a reusable block of code designed to perform a task.

Example:

function greet() {
  console.log("Hello!");
}

2. Why Use Functions?

Functions help you:

  • Avoid repeating code
  • Organize logic
  • Make code cleaner
  • Create modular programs
  • Return values from operations

3. Function Declaration

Also called a named function.

function add(a, b) {
  return a + b;
}

console.log(add(2, 3)); // 5

Features:

  • Hoisted (usable before declaration)

4. Function Expression

Function stored in a variable.

const multiply = function (a, b) {
  return a * b;
};

Features:

  • Not hoisted
  • Can be anonymous or named

5. Arrow Functions

Short syntax introduced in ES6.

const greet = () => {
  console.log("Hi!");
};

Short single-line form:

const square = n => n * n;

Differences from normal functions:

  • No this binding
  • No arguments object
  • Great for callbacks

6. Parameters vs Arguments

Parameters → variables written in function definition Arguments → values passed when calling

Example:

function hello(name) { // parameter
  console.log("Hello", name);
}

hello("Toe"); // argument

7. Default Parameters

function greet(name = "Guest") {
  console.log("Hello", name);
}

8. Rest Parameters (...args)

Used when the number of arguments is unknown.

function sum(...numbers) {
  return numbers.reduce((a, b) => a + b, 0);
}

9. Return Statement

Functions can return a value.

function add(a, b) {
  return a + b;
}

If no return → returns undefined.


10. Anonymous Functions

Functions without a name.

Used in callbacks:

setTimeout(function () {
  console.log("Done");
}, 1000);

11. Callback Functions

A function passed as an argument to another function.

function process(callback) {
  callback();
}

process(() => console.log("Running!"));

12. Higher-Order Functions

Functions that:

  • Take another function as an argument, or
  • Return a function

Example:

function createMultiplier(x) {
  return function (y) {
    return x * y;
  };
}

const double = createMultiplier(2);
console.log(double(5)); // 10

13. Function Scope

Functions create their own scope.

function test() {
  let x = 10;
}
// x is not accessible here

14. Block Scope vs Function Scope

  • let & const → block scoped
  • var → function scoped
if (true) {
  let a = 10; // block
  var b = 20; // function
}
// b is still accessible

15. Closures

A closure is when a function remembers variables from its outer scope.

function outer() {
  let count = 0;
  return function () {
    count++;
    console.log(count);
  };
}

const counter = outer();
counter(); // 1
counter(); // 2

Closures are used in:

  • Private variables
  • Factory functions
  • Module patterns

16. Named vs Anonymous Functions

Named function

function sayHi() {}

Anonymous function

const sayHi = function() {}

17. Immediately Invoked Function Expression (IIFE)

Runs immediately after creation.

(function () {
  console.log("I am an IIFE");
})();

18. Pure vs Impure Functions

Pure

  • No side effects
  • Same input → same output
function add(a, b) {
  return a + b;
}

Impure

let x = 1;
function addToX(y) {
  x += y; // modifies outside variable
}

19. Functions as Objects

Functions in JavaScript are first-class citizens:

  • Can be stored in variables
  • Can be passed as arguments
  • Can be returned from functions

20. Summary

You learned:

  • Function declarations & expressions
  • Arrow functions
  • Parameters, arguments, return values
  • Scope & closures
  • Callbacks & higher-order functions
  • IIFE, pure functions, rest parameters

Functions are the foundation of JavaScript. Mastering them = mastering JS.


Objects

JavaScript objects are one of the most important parts of the language. They let you store data in key-value pairs and model real-world entities.


📌 1. What Is an Object?

An object is a collection of related data and functions.

const user = {
  name: "Alex",
  age: 18,
  isStudent: true,
};
  • Keysname, age, isStudent
  • Values → "Alex", 18, true

📌 2. Creating Objects

A. Object Literal (most common)

const car = {
  brand: "Toyota",
  model: "Vios",
  year: 2020
};

B. Using new Object()

const obj = new Object();
obj.x = 10;
obj.y = 20;

C. Using a Constructor Function

function Person(name, age) {
  this.name = name;
  this.age = age;
}

const p1 = new Person("John", 20);

D. Using Classes (ES6)

class User {
  constructor(name, age) {
    this.name = name;
    this.age = age;
  }
}

const u1 = new User("Alice", 25);

📌 3. Accessing Object Properties

Dot Notation

console.log(user.name);

Bracket Notation

console.log(user["age"]);

Useful when:

  • key contains spaces
  • key is dynamic

📌 4. Adding / Updating Properties

Add new property

user.email = "alex@example.com";

Update existing property

user.age = 19;

📌 5. Deleting Properties

delete user.isStudent;

📌 6. Methods (Functions inside Objects)

const person = {
  name: "Leo",
  greet() {
    console.log(`Hi, I am ${this.name}`);
  }
};

person.greet();

this refers to the current object.


📌 7. Nested Objects

const student = {
  name: "Nyein",
  address: {
    city: "Yangon",
    township: "Hlaing"
  }
};

📌 8. Looping Through Objects

for…in

for (let key in user) {
  console.log(key, user[key]);
}

Object.keys()

console.log(Object.keys(user));

Object.values()

console.log(Object.values(user));

Object.entries()

console.log(Object.entries(user));

📌 9. Copying Objects

Shallow Copy

const copy = { ...user };

Deep Copy

const deepCopy = JSON.parse(JSON.stringify(user));

📌 10. Object Destructuring

const { name, age } = user;
console.log(name, age);

📌 11. Optional Chaining (?.)

Prevents errors when a property might be missing.

console.log(student.address?.city);

📌 12. Useful Built-in Methods

  • Object.keys(obj) → returns keys
  • Object.values(obj) → returns values
  • Object.entries(obj) → returns key/value pairs
  • Object.assign(target, source) → merges objects

📌 13. Real-Life Example

const product = {
  id: 1,
  name: "Laptop",
  price: 980000,
  specs: {
    cpu: "i5",
    ram: "16GB"
  },
  getInfo() {
    return `${this.name} - ${this.price} Ks`;
  }
};

📌 Summary

  • Objects store data in key/value pairs
  • Methods = functions inside objects
  • Dot & bracket notation for access
  • Use destructuring for cleaner code
  • Objects are used everywhere in JS (React, APIs, Node.js)

Arrays

📌 What is an Array?

An array is a special data structure in JavaScript used to store ordered collections of values.

const numbers = [1, 2, 3];
const mixed = ["Hello", 42, true, null];

Arrays are mutable, dynamic, and zero‑indexed.


📌 Array Indexing

  • Index starts from 0
const fruits = ["apple", "banana", "mango"];
console.log(fruits[0]); // apple
console.log(fruits[2]); // mango
  • Accessing an out‑of‑range index returns undefined.

📌 Creating Arrays

1. Using Array literal (recommended)

const arr = [1, 2, 3];

2. Using new Array()

const arr = new Array(5); // creates empty array of length 5

📌 Common Array Methods

🔹 Add & Remove

Action Method Example
Add end push() arr.push(10)
Remove end pop() arr.pop()
Add start unshift() arr.unshift(5)
Remove start shift() arr.shift()
const nums = [1,2,3];
nums.push(4);      // [1,2,3,4]
nums.pop();        // [1,2,3]

🔹 Searching

Method Description
indexOf() Returns index of value
includes() Returns true/false
const colors = ["red", "blue", "green"];
colors.includes("blue"); // true

🔹 Transforming Arrays

map() – returns new array

[1, 2, 3].map(n => n * 2); // [2, 4, 6]

filter() – keeps only matching items

[1, 2, 3, 4].filter(n => n % 2 === 0); // [2, 4]

reduce() – accumulates to a single value

[1, 2, 3].reduce((total, n) => total + n, 0); // 6

📌 Looping Through Arrays

1. for loop

for (let i = 0; i < arr.length; i++) {
  console.log(arr[i]);
}

2. for...of

for (const item of arr) {
  console.log(item);
}

3. forEach()

arr.forEach(item => console.log(item));

📌 Array Destructuring

const [a, b] = [10, 20];
console.log(a); // 10

Skip items:

const [first, , third] = [1,2,3];

📌 Spread & Rest

Spread (expand array)

const arr1 = [1, 2];
const arr2 = [...arr1, 3, 4];

Rest (collect values)

function sum(...nums) {
  return nums.reduce((a, b) => a + b);
}

📌 Useful Utility Methods

slice() – non-destructive

arr.slice(1, 3); // returns part of array

splice() – destructive

arr.splice(1, 1); // removes item at index 1

join() – convert array to string

["a","b"].join("-"); // "a-b"

sort()

[3,1,2].sort(); // [1,2,3]

reverse()

[1,2,3].reverse(); // [3,2,1]

📌 Multidimensional Arrays

const matrix = [
  [1, 2],
  [3, 4]
];
console.log(matrix[1][0]); // 3

📌 When to Use Arrays?

Use arrays when you need ordered data, such as:

  • lists of items
  • API responses
  • user inputs
  • numeric operations
  • loops & transformations

Asynchronous-JavaScript

📌 Introduction

JavaScript is single-threaded, but it can perform non-blocking operations using asynchronous programming.

Async JS allows tasks like:

  • Fetching data from a server
  • Reading files
  • Timers
  • Events

to run without blocking the main thread.


📌 Why Asynchronous JavaScript?

Without async code:

  • Long operations freeze the page
  • UI becomes unresponsive
  • Slow APIs block execution

Async JS lets the browser handle tasks in the background.


1. The Event Loop

The Event Loop is the system that manages asynchronous operations.

JavaScript uses:

  • Call Stack → executes code
  • Web APIs → timers, fetch, DOM
  • Callback Queue → completed tasks
  • Event Loop → sends tasks to stack when it's empty

This enables async behavior even though JS has one thread.


2. Callbacks

A callback is a function passed as an argument.

function getData(callback) {
  setTimeout(() => {
    callback("Done!");
  }, 1000);
}

getData(result => {
  console.log(result);
});

❌ Callback Hell

Nested callbacks become hard to read:

a(() => {
  b(() => {
    c(() => {
      d();
    });
  });
});

3. Promises

A Promise represents a value that will be available in the future.

States:

  • pending
  • fulfilled
  • rejected

Example

const promise = new Promise((resolve, reject) => {
  setTimeout(() => resolve("Success"), 1000);
});

promise.then(result => console.log(result));

.catch() for errors

promise.catch(err => console.error(err));

.finally()

promise.finally(() => console.log("Done"));

4. Async / Await

Introduced in ES2017, async/await lets you write asynchronous code like synchronous code.

Example

async function loadData() {
  const result = await fetch("/api/data");
  const data = await result.json();
  console.log(data);
}

loadData();

Try/Catch for errors

async function run() {
  try {
    const res = await fetch("/invalid");
  } catch (err) {
    console.log("Error:", err);
  }
}

5. Microtasks vs Macrotasks

Microtasks

  • Promise callbacks (then, catch)

Macrotasks

  • setTimeout
  • setInterval

Execution order:

  1. Call Stack
  2. All microtasks
  3. One macrotask
  4. Repeat

6. Common Asynchronous Functions

setTimeout

setTimeout(() => console.log("Hi"), 1000);

setInterval

setInterval(() => console.log("Tick"), 1000);

fetch

fetch("/api").then(res => res.json()).then(data => console.log(data));

7. Parallel, Sequential, and Race

Sequential

await task1();
await task2();

Parallel

await Promise.all([task1(), task2()]);

Race

Promise.race([task1(), task2()]);

8. Error Handling

Promise error

promise.catch(err => console.error(err));

Async/await error

try {
  await something();
} catch (err) {
  console.error(err);
}

9. Real-World Examples

Fetching API Data

async function getUsers() {
  const res = await fetch("https://jsonplaceholder.typicode.com/users");
  return res.json();
}

File Reading (Node.js)

const fs = require("fs/promises");

async function readFile() {
  const data = await fs.readFile("text.txt", "utf8");
  console.log(data);
}

TypeCasting

📌 Introduction

JavaScript is a dynamically typed language, meaning variables can change their type at runtime. Type casting (also called type coercion) is the process of converting one data type to another.

JavaScript performs two types of type casting:

  • Implicit (Automatic) Type Coercion
  • Explicit (Manual) Type Conversion

1. Implicit Type Coercion (Automatic)

JavaScript automatically converts types during operations.

🔹 String Coercion

When one operand is a string → JS converts the other to string.

"5" + 3;   // "53"
5 + "3";   // "53"

🔹 Number Coercion

When using -, *, /, %, JS converts both values to numbers.

"10" - 2;   // 8
"6" * "2"; // 12
"20" / 5;   // 4

🔹 Boolean Coercion

Values are converted to true/false in logical contexts.

Falsy values:

false, 0, "", null, undefined, NaN

Everything else → true

Boolean(0);      // false
Boolean("Hi");  // true

2. Explicit Type Conversion (Manual)

You convert types using built-in functions.


2.1 Convert to Number

Use:

  • Number(value)
  • parseInt(value)
  • parseFloat(value)
  • Unary +value
Number("10");     // 10
parseInt("10px"); // 10
parseFloat("9.5"); // 9.5
+"5";             // 5

❗ Invalid conversions

Number("hello"); // NaN

2.2 Convert to String

Use:

  • String(value)
  • .toString()
String(123);     // "123"
(100).toString(); // "100"

2.3 Convert to Boolean

Use:

  • Boolean(value)
  • !!value
Boolean(1);  // true
Boolean(0);  // false
!!"hi";     // true

3. Common Coercion Scenarios

🔹 With + operator

  • If one operand = string → convert to string
1 + "2"; // "12"

🔹 With comparison ==

JavaScript tries to convert values to the same type

"5" == 5; // true
true == 1; // true
false == 0; // true

🔹 Strict comparison ===

No type coercion

"5" === 5; // false

4. Type Coercion Table

Expression Result
true + 1 2
false + 1 1
"5" * 2 10
"5" + 2 "52"
null + 1 1
undefined + 1 NaN

5. Checking Types

typeof "hello"; // "string"
typeof 50;      // "number"
typeof true;    // "boolean"
typeof null;    // "object" (known JS bug)
typeof []       // "object"

6. Best Practices

✔ Use explicit conversion instead of relying on coercion ✔ Avoid using loose equality (==) ✔ Use strict equality (===) ✔ Use Number() instead of parseInt() when possible ✔ Be careful with + → it triggers string coercion


Modules

📌 Introduction

JavaScript modules allow you to split your code into reusable, maintainable files. Each module can export variables/functions/classes and another file can import them.

Modules help with:

  • Better code organization
  • Reusability
  • Avoiding global namespace pollution
  • Easier maintenance
  • Cleaner architecture

Modern JavaScript uses ES Modules (ESM).


1. ES Modules (ESM)

The modern module system using:

import ... from "module";
export ...;

Supported in:

  • Browsers (using <script type="module">)
  • Node.js (with .mjs or package.json type: module)

2. Exporting

Exports allow a file to expose code so other files can import it.

🔹 Named Exports

You can export multiple items.

// math.js
export const PI = 3.14;
export function add(a, b) {
  return a + b;
}

🔹 Default Export

One file can have only one default export.

// greet.js
export default function greet(name) {
  console.log(`Hello, ${name}`);
}

3. Importing

🔹 Import Named Exports

import { PI, add } from "./math.js";
console.log(add(2, 3));

🔹 Import Default Export

import greet from "./greet.js";
greet("Koko");

🔹 Rename Imports

import { add as sum } from "./math.js";

🔹 Import Everything

import * as math from "./math.js";
math.add(2, 3);
math.PI;

4. Mixing Exports

You can mix named + default exports.

// utils.js
export default function log(msg) {
  console.log(msg);
}
export const version = "1.0.0";
import log, { version } from "./utils.js";

5. Module Execution

  • A module is executed only once, even if imported multiple times.
  • Imports are read before code runs (top-level scope).
  • Modules always run in strict mode.

6. Using Modules in Browser

<script type="module" src="/app.js"></script>

Features:

  • Modules load deferred automatically
  • import works inside scripts

7. Modules in Node.js

Option 1: Use .mjs

node app.mjs

Option 2: Add to package.json

{
  "type": "module"
}

Then use:

import { add } from "./math.js";

8. CommonJS vs ES Modules

Feature CommonJS ES Modules
Syntax require/export import/export
Loaded runtime compile-time
File Ext .js .mjs or js w/ type: module
Default Node.js Browser + Node

CommonJS Example

const fs = require("fs");
module.exports = {};

ES Module Example

import fs from "fs";
export default {};

9. Dynamic Imports

Useful for lazy loading or conditional imports.

if (true) {
  const module = await import("./math.js");
  console.log(module.add(2, 3));
}

10. Real-World Example Structure

project/
 ├─ utils/
 │   ├─ math.js
 │   └─ helpers.js
 ├─ components/
 │   └─ navbar.js
 └─ app.js

math.js

export function multiply(a, b) {
  return a * b;
}

app.js

import { multiply } from "./utils/math.js";
console.log(multiply(4, 5));

11. Best Practices

✔ Use named exports when exporting many items ✔ Use default export when exporting a single main value ✔ Keep file names descriptive ✔ Group similar modules into folders ✔ Avoid circular imports ✔ Prefer ES Modules over CommonJS for new projects


ErrorHandling

📌 Introduction

Error handling in JavaScript allows you to catch and manage errors so your program doesn’t crash unexpectedly. Errors can happen due to:

  • Invalid input
  • Network failure
  • Wrong code logic
  • Unexpected API responses
  • Missing files (Node.js)

JavaScript provides tools like try/catch, throw, finally, and error objects to manage these situations safely.


1. Types of Errors in JavaScript

🔹 Syntax Error

Code cannot run due to incorrect syntax.

console.log("Hello"   // missing parenthesis

🔹 Reference Error

Using a variable that does not exist.

console.log(x); // x is not defined

🔹 Type Error

Wrong operation on the wrong data type.

const num = 5;
num.toUpperCase(); // TypeError

🔹 Range Error

Invalid length or number range.

new Array(-2); // RangeError

🔹 Custom Errors (using throw)

You can throw your own custom errors.

throw new Error("Something went wrong!");

2. try / catch

Used to handle errors gracefully.

try {
  const result = dangerousFunction();
} catch (error) {
  console.log("Error happened:", error);
}

3. finally Block

Runs always, whether there's an error or not.

try {
  console.log("Trying...");
} catch (err) {
  console.log("Error!");
} finally {
  console.log("Always runs");
}

4. Throwing Custom Errors

Use throw to trigger your own error.

function divide(a, b) {
  if (b === 0) {
    throw new Error("Cannot divide by zero");
  }
  return a / b;
}

5. The Error Object

JavaScript error objects contain useful information:

try {
  throw new Error("Failed to load");
} catch (e) {
  console.log(e.name);    // "Error"
  console.log(e.message); // "Failed to load"
  console.log(e.stack);   // stack trace
}

Common error types:

  • Error
  • TypeError
  • ReferenceError
  • SyntaxError
  • RangeError
  • EvalError

6. Error Handling in Asynchronous Code

🔹 Callbacks

fs.readFile("test.txt", (err, data) => {
  if (err) return console.error(err);
  console.log(data);
});

🔹 Promises

fetch("/api")
  .then(res => res.json())
  .catch(err => console.log("Error:", err));

🔹 async / await with try/catch

async function loadData() {
  try {
    const res = await fetch("/api/users");
    const data = await res.json();
  } catch (error) {
    console.log("Failed to load:", error);
  }
}

7. Global Error Handling

🔹 Browser

window.onerror = function(message, source, line, column, error) {
  console.log("Global Error: ", message);
};

🔹 Node.js

process.on("uncaughtException", (err) => {
  console.log("Unhandled Exception:", err);
});

8. Validation Errors

Throw custom errors when data is invalid.

function register(user) {
  if (!user.name) {
    throw new Error("Name is required");
  }
}

9. Error Logging (Best Practices)

✔ Log errors clearly ✔ Include timestamp ✔ Never show internal errors to users ✔ Use monitoring tools (Sentry, LogRocket, Datadog) ✔ Use custom error classes for clarity


10. Creating Custom Error Classes

class ValidationError extends Error {
  constructor(message) {
    super(message);
    this.name = "ValidationError";
  }
}

throw new ValidationError("Invalid email format");

11. Best Practices

✔ Use try/catch only where needed ✔ Throw meaningful error messages ✔ Clean and consistent error structure ✔ Handle async errors with try/catch or .catch() ✔ Avoid silent error handling ✔ Use custom errors for validation and logic problems


OOPConpects

JavaScript supports Object-Oriented Programming (OOP) using prototypes and ES6 classes.


🚀 What is OOP?

OOP is a programming paradigm that organizes code into objects — each object contains data (properties) and behavior (methods).

JavaScript implements OOP using:

  • Objects
  • Prototypes
  • Constructor functions
  • Classes (ES6)

✅ Core OOP Concepts

1. Classes

A class is a blueprint for creating objects.

class Person {
  constructor(name, age) {
    this.name = name;
    this.age = age;
  }

  greet() {
    console.log(`Hello, my name is ${this.name}`);
  }
}

const p1 = new Person("John", 20);
p1.greet();

2. Objects

Objects are instances created from classes.

const user = new Person("Alice", 25);

3. Constructor

The constructor() method initializes object properties.

class Car {
  constructor(brand, year) {
    this.brand = brand;
    this.year = year;
  }
}

4. Encapsulation

Encapsulation hides internal details and protects data.

Modern JS supports private fields:

class BankAccount {
  #balance = 0; // private

  deposit(amount) {
    this.#balance += amount;
  }

  getBalance() {
    return this.#balance;
  }
}

5. Abstraction

Abstraction shows only essential features and hides complexity.

class CoffeeMachine {
  start() {
    this._heatWater();
    console.log("Coffee ready!");
  }

  _heatWater() { // Pretend private
    console.log("Heating...");
  }
}

6. Inheritance

One class can inherit properties & methods from another.

class Animal {
  speak() {
    console.log("Animal sound");
  }
}

class Dog extends Animal {
  speak() {
    console.log("Woof!");
  }
}

const d = new Dog();
d.speak();

7. Polymorphism

Child classes can override parent class methods.

Example above: Dog.speak() overrides Animal.speak().

Another example:

class Shape {
  area() {
    return 0;
  }
}

class Circle extends Shape {
  constructor(r) {
    super();
    this.r = r;
  }

  area() {
    return Math.PI * this.r * this.r;
  }
}

8. The "this" Keyword

this refers to the current object instance.

class User {
  constructor(name) {
    this.name = name; // "this" = current object
  }
}

9. Static Methods

Static methods belong to the class (not instances).

class MathUtils {
  static add(a, b) {
    return a + b;
  }
}

MathUtils.add(5, 3); // OK

10. Prototypes (Behind the Scenes)

Before ES6 classes, OOP in JS used prototypes.

function Person(name) {
  this.name = name;
}

Person.prototype.greet = function () {
  console.log("Hello " + this.name);
};

🔥 Summary Table

Concept Description
Class Blueprint for objects
Object Instance of a class
Constructor Initializes properties
Encapsulation Hiding data, using private fields
Abstraction Hiding complexity
Inheritance Reusing parent class features
Polymorphism Overriding methods
Static methods Methods used on class, not object
Prototype JS's underlying OOP system

📘 Real-World Example

class User {
  constructor(username) {
    this.username = username;
  }

  login() {
    console.log(this.username + " logged in");
  }
}

class Admin extends User {
  deleteUser(user) {
    console.log(`Admin deleted ${user.username}`);
  }
}

const admin = new Admin("Admin1");
const user = new User("Tom");

admin.login();
admin.deleteUser(user);

JSON

JSON is one of the most important data formats in modern web development. It is used to store, exchange, and transport data between servers, APIs, and applications.


📌 What is JSON?

JSON stands for JavaScript Object Notation.

It is:

  • A text-based data format
  • Lightweight
  • Easy for humans to read
  • Easy for machines to parse
  • Language-independent (not only for JavaScript)

Example JSON:

{
  "name": "John",
  "age": 25,
  "isStudent": false,
  "skills": ["HTML", "CSS", "JavaScript"]
}

📦 JSON vs JavaScript Object

JSON

{
  "name": "John",
  "age": 25
}
  • Keys are always strings (double quotes)
  • Cannot contain functions
  • Only supports values: string, number, object, array, boolean, null

JavaScript Object

const user = {
  name: "John",
  age: 25,
  greet() {
    console.log("Hello");
  }
};
  • Keys can be without quotes
  • Can contain methods & variables

💡 Valid JSON Data Types

Type Example
String "Hello"
Number 10, 2.5
Boolean true / false
Object { "a": 1 }
Array [1, 2, 3]
Null null

⛔ JSON does not support:

  • Functions
  • Comments
  • Undefined
  • Date objects (must be a string)

🔄 Converting JSON in JavaScript

1. JSON.stringify() → Convert JS object to JSON string

const user = {
  name: "Alice",
  age: 20
};

const jsonData = JSON.stringify(user);
console.log(jsonData);
// "{"name":"Alice","age":20}""

This is often used when:

  • Sending data to a server
  • Saving data in localStorage

2. JSON.parse() → Convert JSON string to JS object

const json = '{"name":"Alice","age":20}';

const obj = JSON.parse(json);
console.log(obj.name); // Alice

Used when:

  • Receiving data from API
  • Reading from localStorage

🖥️ Real API Example

fetch("https://api.example.com/user")
  .then(res => res.json()) // parse JSON response
  .then(data => console.log(data));

📁 JSON in Local Storage

const user = { name: "Tom", age: 30 };

// Save
localStorage.setItem("user", JSON.stringify(user));

// Read
const data = JSON.parse(localStorage.getItem("user"));
console.log(data.name);

🚫 Common Errors

❌ 1. Using single quotes in JSON

{
  'name': 'John'  // ❌ invalid
}

JSON requires double quotes.


❌ 2. Trailing commas

{
  "name": "John",
  "age": 30,   // ❌ invalid
}

❌ 3. Comments not allowed

{
  "name": "John" // ❌ comments not allowed
}

📌 JSON.stringify Additional Options

Pretty Format

const json = JSON.stringify(user, null, 2);
console.log(json);

Output:

{
  "name": "Alice",
  "age": 20
}

🔥 Summary

Feature Description
JSON Data exchange format
stringify() JS → JSON string
parse() JSON string → JS object
Data types string, number, object, array, boolean, null
Used in APIs, databases, configs, localStorage

FetchAPI

The Fetch API is a modern, promise-based way to make HTTP requests in JavaScript. It is widely used in web development for calling APIs, sending data to servers, and retrieving JSON.


🚀 What is Fetch API?

fetch() is a built-in browser function that allows you to request resources over the network.

Basic syntax:

fetch(url, options?)
  .then(response => response.json())
  .then(data => console.log(data))
  .catch(error => console.error(error));

📌 1. Basic GET Request

fetch("https://api.example.com/users")
  .then(res => res.json())
  .then(data => console.log(data))
  .catch(err => console.log(err));

📌 2. Using Async/Await (Recommended)

async function getUsers() {
  try {
    const res = await fetch("https://api.example.com/users");
    const data = await res.json();
    console.log(data);
  } catch (err) {
    console.error(err);
  }
}

📌 3. POST Request (Send Data)

async function createUser() {
  const newUser = {
    name: "John",
    age: 22
  };

  const res = await fetch("https://api.example.com/users", {
    method: "POST",
    headers: {
      "Content-Type": "application/json"
    },
    body: JSON.stringify(newUser)
  });

  const data = await res.json();
  console.log(data);
}

📌 4. PUT Request (Update Data)

fetch("https://api.example.com/users/1", {
  method: "PUT",
  headers: { "Content-Type": "application/json" },
  body: JSON.stringify({ name: "Updated User" })
})
  .then(res => res.json())
  .then(data => console.log(data));

📌 5. DELETE Request

await fetch("https://api.example.com/users/1", {
  method: "DELETE"
});

📌 6. Handling Errors Correctly

fetch() does NOT throw errors for HTTP status codes like 404 or 500. You must check them manually:

async function loadData() {
  try {
    const res = await fetch("https://api.example.com/data");

    if (!res.ok) {
      throw new Error(`HTTP Error: ${res.status}`);
    }

    const data = await res.json();
    console.log(data);
  } catch (error) {
    console.error("Fetch Error:", error);
  }
}

📌 7. Sending Headers

fetch(url, {
  headers: {
    "Authorization": "Bearer token123",
    "Content-Type": "application/json"
  }
});

📌 8. Fetching Text, Blob, FormData, etc.

Text

const res = await fetch("/info.txt");
const text = await res.text();

Blob (images/files)

const res = await fetch("/image.png");
const blob = await res.blob();

FormData

const formData = new FormData();
formData.append("photo", fileInput.files[0]);

await fetch("/upload", {
  method: "POST",
  body: formData
});

📌 9. Abort Fetch Request

Cancel a long-running request:

const controller = new AbortController();

fetch(url, { signal: controller.signal });

controller.abort();

📌 10. Fetch Options Summary

Option Description
method GET, POST, PUT, DELETE
headers Additional metadata (JSON, Auth, etc.)
body Request payload
signal AbortController for canceling

📌 11. Real-World Example: Pagination

async function loadPage(page) {
  const res = await fetch(`/api/users?page=${page}`);
  const data = await res.json();
  console.log(data);
}

📦 12. Fetch in Next.js (App Router)

export async function GET() {
  const res = await fetch("https://api.example.com/products", {
    cache: "no-store"
  });
  const data = await res.json();
  return Response.json(data);
}

🔥 Summary

  • fetch() is Promise-based
  • Supports GET, POST, PUT, DELETE
  • Use res.json() to convert API response
  • Must manually check res.ok
  • Supports headers, FormData, Blob, File uploads
  • Works great with async/await

ES6

ES6+ refers to ECMAScript 2015 (ES6) and all versions after it. It introduced many powerful features that make JavaScript cleaner, faster, and easier to write.


🚀 1. let and const

let

  • Block scoped
  • Can be reassigned
let age = 20;
age = 21;

const

  • Block scoped
  • Cannot be reassigned
const name = "Alex";

🚀 2. Arrow Functions

Shorter, cleaner syntax.

const add = (a, b) => a + b;

Arrow functions do not have their own this.


🚀 3. Template Literals

Use backticks `, variable interpolation, and multiline strings.

const name = "John";
console.log(`Hello ${name}!`);

🚀 4. Default Parameters

function greet(name = "Guest") {
  console.log(`Hello ${name}`);
}

🚀 5. Destructuring

Object Destructuring

const user = { name: "Tom", age: 30 };
const { name, age } = user;

Array Destructuring

const nums = [10, 20, 30];
const [a, b] = nums;

🚀 6. Spread Operator ...

Spread into arrays

const arr1 = [1,2];
const arr2 = [...arr1, 3, 4];

Spread into objects

const user = { name: "Alice" };
const newUser = { ...user, age: 22 };

🚀 7. Rest Parameters

function sum(...nums) {
  return nums.reduce((a, b) => a + b);
}

🚀 8. Enhanced Object Literals

const name = "John";
const age = 20;

const user = {
  name,
  age,
  greet() {
    console.log("Hello!");
  }
};

🚀 9. Modules (import/export)

// math.js
export function add(a, b) { return a + b; }

// app.js
import { add } from "./math.js";

🚀 10. Classes

class Person {
  constructor(name) {
    this.name = name;
  }

  speak() {
    console.log(`${this.name} speaks`);
  }
}

🚀 11. Promises

const getData = () => new Promise((resolve) => {
  resolve("Done");
});

🚀 12. Async/Await

Cleaner way to handle asynchronous code.

async function load() {
  const data = await fetch("/api");
}

🚀 13. Optional Chaining ?.

Safer property access.

console.log(user?.address?.city);

🚀 14. Nullish Coalescing ??

Returns right value only if left is null or undefined.

const username = input ?? "Guest";

🚀 15. Map and Set

Set

const set = new Set([1,2,2,3]);

Map

const map = new Map();
map.set("name", "John");

🚀 16. Iterators & for...of

for (const value of [10,20,30]) {
  console.log(value);
}

🚀 17. Symbol

Unique identifier.

const id = Symbol("id");

🚀 18. BigInt

Large integers.

const n = 12345678901234567890n;

🚀 19. Dynamic Import

import("./module.js").then(module => {
  module.run();
});

🚀 20. Promise.all, Promise.any, Promise.race

await Promise.all([p1, p2]);

🔥 Summary Table

Feature Description
let/const Block-scoped variables
Arrow functions Shorter, no this
Template literals Backtick strings
Destructuring Extract values
Spread/Rest Expand or collect
Classes OOP support
Promises Async operations
Async/await Cleaner async
Optional chaining Safe access
Modules import/export

BrowserAPIs

Browser APIs (Application Programming Interfaces) are built-in features provided by web browsers that allow JavaScript to interact with the browser and the environment.

They let you:

  • Manipulate the DOM
  • Handle user events
  • Store data
  • Work with multimedia
  • Access device features
  • Fetch network resources

🌳 1. DOM (Document Object Model) API

The DOM API lets JavaScript interact with HTML elements.

Select Elements

document.getElementById("title");
document.querySelector(".item");

Modify Elements

const title = document.querySelector("h1");
title.textContent = "Updated Title";
title.style.color = "blue";

Create & Append Elements

const div = document.createElement("div");
div.textContent = "Hello";
document.body.appendChild(div);

🎯 2. Events API

Handle clicks, input, submit, keyboard, scroll, etc.

document.querySelector("button").addEventListener("click", () => {
  console.log("Button clicked!");
});

💾 3. Storage API (localStorage & sessionStorage)

localStorage

  • Stores data permanently (until deleted)
localStorage.setItem("theme", "dark");
localStorage.getItem("theme");

sessionStorage

  • Stores data for one tab session
sessionStorage.setItem("token", "123");

🌐 4. Fetch API

Used to make HTTP requests.

fetch("/api/data")
  .then(res => res.json())
  .then(data => console.log(data));

⏱️ 5. Timers (setTimeout, setInterval)

setTimeout(() => {
  console.log("Runs once after 2 seconds");
}, 2000);

setInterval(() => {
  console.log("Repeats every second");
}, 1000);

🎥 6. Geolocation API

Retrieve user location (with permission).

navigator.geolocation.getCurrentPosition(pos => {
  console.log(pos.coords.latitude, pos.coords.longitude);
});

🎤 7. Media Devices & Camera API

Access camera/microphone.

navigator.mediaDevices.getUserMedia({ video: true })
  .then(stream => console.log(stream));

🔊 8. Audio & Video API

Control audio and video elements.

document.querySelector("video").play();
document.querySelector("audio").pause();

🗂️ 9. Clipboard API

Copy text to clipboard.

navigator.clipboard.writeText("Copied!");

Paste (with permission):

navigator.clipboard.readText().then(text => console.log(text));

🖼️ 10. Canvas API

Used for drawing graphics.

const canvas = document.getElementById("myCanvas");
const ctx = canvas.getContext("2d");
ctx.fillStyle = "red";
ctx.fillRect(10, 10, 100, 100);

🌐 11. History API

Manage browser navigation.

history.pushState({ page: 1 }, "Title", "?page=1");

💨 12. Web Storage API

Includes:

  • localStorage
  • sessionStorage
  • Cookies (via document.cookie)

🕸️ 13. WebSocket API

Real-time communication.

const socket = new WebSocket("ws://example.com");
socket.onmessage = event => console.log(event.data);

🔔 14. Notification API

Show system notifications.

Notification.requestPermission().then(() => {
  new Notification("Hello!");
});

🔄 15. Intersection Observer API

Detect when elements enter the viewport.

const observer = new IntersectionObserver(entries => {
  if (entries[0].isIntersecting) {
    console.log("Element visible");
  }
});

observer.observe(document.querySelector("#target"));

🧭 16. URL & URLSearchParams API

const url = new URL(window.location);
console.log(url.searchParams.get("id"));

🔥 Summary Table

API Purpose
DOM API Work with HTML elements
Events API User interactions
Storage API localStorage / sessionStorage
Fetch API Make network requests
Geolocation Get location
MediaDevices Camera/Mic access
Canvas Draw graphics
WebSocket Real-time data
Notification System notifications
Timers setTimeout, setInterval
URL API Parse/manipulate URLs

Hoisting

Hoisting ဆိုတာ JavaScript မှာ variable တွေနဲ့ function တွေကို code မ run ခင် 
(Execution context တည်ဆောက်တဲ့အချိန်) memory ထဲမှာ နေရာကြိုယူထားတဲ့ သဘောတရားဖြစ်ပါတယ်။

ရိုးရိုးရှင်းရှင်းပြောရရင် သင်က variable တစ်ခုကို မကြေညာခင် (Declare မလုပ်ခင်) အပေါ်ကနေ လှမ်းသုံးလိုက်ရင်တောင် 
JavaScript က error မတက်စေဘဲ variable declaration ကို code ရဲ့ ထိပ်ဆုံးကို ဆွဲတင်လိုက်သလိုမျိုး 
ပြုမူတာကို ခေါ်တာပါ။

၁။ Function Hoisting
Function တွေက Hoisting မှာ အထူးအခွင့်အရေးရပါတယ်။ Function တစ်ခုလုံးကို memory ထဲ ကြိုတင်သိမ်းထားတဲ့အတွက် 
သူ့ကို မရေးခင် (အပေါ်ကနေ) လှမ်းခေါ်လို့ ရပါတယ်။


sayHello(); // အလုပ်လုပ်တယ်: "မင်္ဂလာပါ"

function sayHello() {
  console.log("မင်္ဂလာပါ");
}


၂။ Variable Hoisting (var, let, const)

Variable တွေမှာတော့ သူတို့ကို ကြေညာတဲ့ keyword ပေါ်မူတည်ပြီး အလုပ်လုပ်ပုံ ကွာခြားပါတယ်။

var: Hoisting ဖြစ်ပါတယ်။ ဒါပေမဲ့ variable ရဲ့ တန်ဖိုး (value) ကိုတော့ မသိသေးဘဲ undefined 
အဖြစ်ပဲ မှတ်ထားပါတယ်။

let နှင့် const: သူတို့လည်း Hoisting ဖြစ်ပါတယ်။ ဒါပေမဲ့ သူတို့ကို memory ထဲမှာ နေရာယူထားရုံပဲ
 ရှိပြီး code က သူတို့ဆီ မရောက်မချင်း အသုံးပြုခွင့် မပေးပါဘူး။ ဒါကို Temporal Dead Zone (TDZ) လို့ ခေါ်ပါတယ်။

** Temporal Dead Zone (TDZ) ဆိုတာ let နဲ့ const variable တွေမှာ ဖြစ်လေ့ရှိတဲ့ အပြုအမူတစ်ခုပါ။
variable ကို စတင်ကြေညာ (declare) တဲ့ code အကြောင်းဆီ မရောက်ခင် အပေါ်ကနေ လှမ်းသုံးမိရင်
ReferenceError တက်စေတဲ့ နယ်မြေ (Area) ကို ခေါ်တာ ဖြစ်ပါတယ်။**

Keyword Hoisted ဖြစ်လား တန်ဖိုး (Initial Value) Error တက်လား
var ဖြစ်တယ် undefined မတက်ဘူး(undefined ပြမယ်)
let / const ဖြစ်တယ် မရှိဘူး (Uninitialized) ReferenceError တက်မယ်

Scope

Scope ဆိုတာ JavaScript မှာ variable တွေ၊ functions တွေနဲ့ objects တွေကို 
"ဘယ်နေရာကနေ လှမ်းသုံးလို့ရသလဲ" ဆိုတဲ့ အတိုင်းအတာ သို့မဟုတ် နယ်နိမိတ်ကို ခေါ်တာ ဖြစ်ပါတယ်။

ရိုးရိုးရှင်းရှင်းပြောရရင် Variable တစ်ခုရဲ့ "သက်တမ်း" နဲ့ "မြင်နိုင်စွမ်း" (Visibility) ကို Scope က ဆုံးဖြတ်ပေးတာပါ။

၁။ Scope အမျိုးအစား (၃) မျိုး

JavaScript မှာ အဓိကအားဖြင့် အောက်ပါ Scope ၃ ခု ရှိပါတယ်-

(က) Global Scope

မည်သည့် function သို့မဟုတ် block ရဲ့ အပြင်ဘက်မှာမဆို ကြေညာထားတဲ့ variable တွေပါ။

ထူးခြားချက်: Code တစ်ခုလုံးရဲ့ ဘယ်နေရာကနေမဆို လှမ်းသုံးလို့ရပါတယ်။

ဥပမာ: const website = "Google"; (ဒါကို function ထဲကနေလည်း လှမ်းခေါ်လို့ ရပါတယ်)


(ခ) Function Scope (Local Scope)

Function တစ်ခုရဲ့ { } အတွင်းမှာ ကြေညာထားတဲ့ variable တွေပါ။

ထူးခြားချက်: အဲဒီ function အတွင်းမှာပဲ သုံးလို့ရပါတယ်။ Function အပြင်ဘက်ကနေ လှမ်းခေါ်ရင် Error တက်ပါလိမ့်မယ်။

var keyword နဲ့ ကြေညာရင် Function Scope ဖြစ်ပါတယ်။

(ဂ) Block Scope

if statement, for loop သို့မဟုတ် ရိုးရိုး curly braces { } အတွင်းမှာ ရှိတဲ့ နေရာပါ။

ထူးခြားချက်: let နဲ့ const ကို သုံးမှသာ Block Scope အလုပ်လုပ်ပါတယ်။ (အဲဒီ { } အပြင်ဘက်မှာ သုံးလို့မရပါ)

သတိထားရန်: var နဲ့ ကြေညာရင် block scope မရှိပါဘူး (Global သို့မဟုတ် Function scope ဆီကို ပေါက်ထွက်သွားပါလိမ့်မယ်)။

၂။ နှိုင်းယှဉ်ချက် ဥပမာ


// --- Global Scope ---
const user = "Aung Aung"; 

function sayHi() {
    // --- Function Scope ---
    const message = "Hello"; 
    
    if (true) {
        // --- Block Scope ---
        const greeting = "Hi there";
        var legacy = "I am everywhere"; // var သည် block scope ကို ဖောက်ထွက်နိုင်သည်
        console.log(greeting); // အလုပ်လုပ်သည်
    }

    console.log(message);  // အလုပ်လုပ်သည်
    // console.log(greeting); // Error! (Block Scope အပြင်ဘက်ဖြစ်နေ၍)
    console.log(legacy);   // အလုပ်လုပ်သည် (var ဖြစ်သောကြောင့်)
}

sayHi();
// console.log(message); // Error! (Function Scope အပြင်ဘက်ဖြစ်နေ၍)

၃။ ဘာကြောင့် Scope က အရေးကြီးတာလဲ?

Security (လုံခြုံမှု): Variable တွေကို လိုအပ်တဲ့ နေရာမှာပဲ ထားခြင်းဖြင့် အခြား code တွေက မတော်တဆ 
လာပြင်တာမျိုးကို တားဆီးနိုင်ပါတယ်။

Naming Collisions (နာမည်တူခြင်း): Scope မတူရင် variable နာမည်တူပေးလို့ ရပါတယ်။
 (ဥပမာ- function A ထဲမှာလည်း x သုံး၊ function B ထဲမှာလည်း x သုံးလို့ ရတာမျိုး)

Memory Management: Function တစ်ခု အလုပ်ပြီးသွားရင် သူ့ထဲက Local variables တွေကို
 memory ထဲကနေ ဖျက်ထုတ်ပေးတဲ့အတွက် memory သက်သာစေပါတယ်။

အနှစ်ချုပ်

Global Scope: လူတိုင်း မြင်နိုင်တဲ့ "လမ်းမပေါ်က ဆိုင်းဘုတ်" လိုမျိုးပါ။

Function Scope: အိမ်တစ်အိမ်ရဲ့ "ဧည့်ခန်း" လိုမျိုးပါ။ အိမ်ထဲဝင်မှ မြင်ရပါတယ်။

Block Scope: အိမ်ထဲကမှ "သေတ္တာအသေးလေး" ထဲ ထည့်ထားသလိုမျိုးပါ။ အဲဒီသေတ္တာကို ဖွင့်မှပဲ မြင်ရတာပါ။

Scope Chain

Scope Chain ဆိုတာ JavaScript မှာ variable တစ်ခုကို ရှာဖွေတဲ့ "လှေကားထစ်" လိုမျိုး စနစ်တစ်ခု ဖြစ်ပါတယ်။
လက်ရှိရှိနေတဲ့ နေရာမှာ variable ကို ရှာလို့မတွေ့ရင် သူ့ရဲ့ အပြင်ဘက် (Parent Scope) ဆီကို အဆင့်ဆင့် 
တက်ရှာသွားတဲ့ ဖြစ်စဉ်ကို ခေါ်တာပါ။

ဒီ concept ကို နားလည်ဖို့ Scopes အမျိုးအစားတွေကို အရင်သိထားဖို့ လိုပါတယ်။

၁။ Scopes အမျိုးအစား ၃ ခု
Global Scope: Code တစ်ခုလုံးရဲ့ အပြင်ဘက်ဆုံးနေရာ။ ဘယ်နေရာကမဆို လှမ်းသုံးလို့ရတယ်။

Function Scope: Function တစ်ခုအတွင်းမှာပဲ ရှိတဲ့နေရာ။

Block Scope: if သို့မဟုတ် for loop ရဲ့ { } brackets အတွင်းမှာပဲ ရှိတဲ့နေရာ (let နဲ့ const အတွက်သာ)။

၂။ Scope Chain ဘယ်လို အလုပ်လုပ်သလဲ?

JavaScript Engine က variable တစ်ခုကို တွေ့တဲ့အခါ အောက်ပါအစီအစဉ်အတိုင်း ရှာဖွေပါတယ်-

Local Scope: အရင်ဆုံး လက်ရှိ အလုပ်လုပ်နေတဲ့ နေရာ (Current Scope) မှာ ရှာပါတယ်။

Outer Scope: မတွေ့ရင် သူ့ကို ဝန်းရံထားတဲ့ အပြင်ဘက် Scope (Parent) ဆီကို သွားရှာပါတယ်။

Global Scope: အပြင်ဘက်အဆင့်ဆင့်မှာ ရှာရင်းနဲ့ နောက်ဆုံး Global Scope အထိ ရောက်သွားပါတယ်။ 
အဲဒီမှာမှ မတွေ့တော့ဘူးဆိုရင်တော့ ReferenceError ပြပါလိမ့်မယ်။

အရေးကြီးချက်: Scope Chain ဟာ အောက်ကနေ အပေါ်ကိုပဲ ရှာလို့ရပါတယ်။ အပေါ် (Global) ကနေ 
အောက် (Local function) ထဲက variable ကို လှမ်းရှာလို့ မရပါဘူး။

၃။ Code ဥပမာဖြင့် ကြည့်ခြင်း

const globalVar = "Global";

function outerFunction() {
    const outerVar = "Outer";

    function innerFunction() {
        const innerVar = "Inner";

        console.log(innerVar);  // ၁။ Local မှာတွေ့တယ် -> "Inner"
        console.log(outerVar);  // ၂။ Local မှာမတွေ့လို့ Parent (outerFunction) မှာသွားရှာတယ် -> "Outer"
        console.log(globalVar); // ၃။ Parent မှာမတွေ့လို့ Global မှာသွားရှာတယ် -> "Global"
        console.log(unknown);   // ၄။ ဘယ်မှာမှမတွေ့လို့ -> ReferenceError
    }

    innerFunction();
}

outerFunction();

၄။ Lexical Scoping
Scope Chain ဟာ Lexical Scoping ပေါ်မှာ အခြေခံပါတယ်။ ဆိုလိုတာက variable တစ်ခုရဲ့ scope ကို
code ရေးကတည်းက (ဘယ်နေရာမှာ ရေးထားသလဲဆိုတာကို ကြည့်ပြီး) ဆုံးဖြတ်လိုက်တာပါ။ Function ကို 
ဘယ်နေရာမှာ "ခေါ်သလဲ" ဆိုတာထက် ဘယ်နေရာမှာ "ရေးထားသလဲ" ဆိုတာက ပိုအရေးကြီးပါတယ်။

အကျဉ်းချုပ် (Analogy)

အိမ်တစ်အိမ်မှာ ပစ္စည်းတစ်ခု ရှာသလိုပါပဲ-

ကိုယ့်အခန်းထဲမှာ အရင်ရှာမယ် (Local Scope)။

မတွေ့ရင် ဧည့်ခန်းထဲထွက်ရှာမယ် (Outer Scope)။

မတွေ့ရင် အိမ်ရှေ့ကွင်းပြင်ထဲမှာ ထွက်ရှာမယ် (Global Scope)။

အပြင်မှာမှ မတွေ့ရင်တော့ အဲဒီပစ္စည်း မရှိဘူးလို့ သတ်မှတ်လိုက်တာပါပဲ။

Lexical Scoping

JavaScript မှာ Lexical Scope (သို့မဟုတ် Static Scope) ဆိုသည်မှာ variable တစ်ခု၏ 
တည်ရှိမှုနယ်ပယ် (Scope) ကို ၎င်းအား code ရေးသားစဉ်က ထားရှိခဲ့သော နေရာ  ပေါ်မူတည်၍
သတ်မှတ်ခြင်းကိုဆိုလိုပါသည်။

ရိုးရိုးရှင်းရှင်းပြောရရင် "Function တစ်ခုဟာ သူ့ရဲ့ အပြင်ဘက် (Parent) မှာရှိတဲ့ Variable တွေကို လှမ်းမြင်နိုင်တယ်" 
ဆိုတာပါပဲ။ 

function outer() {
  const name = "Aung Aung";

  function inner() {
    // inner function ထဲမှာ 'name' မရှိပေမဲ့
    // သူ့ရဲ့ lexical parent ဖြစ်တဲ့ outer ဆီက variable ကို လှမ်းသုံးလို့ရတယ်
    console.log(name); 
  }

  inner();
}

outer(); // Output: Aung Aung
ဒီနေရာမှာ inner() function ကို outer() ရဲ့ အထဲမှာ ရေးထားတဲ့အတွက် inner ရဲ့ lexical environment
 ထဲမှာ outer ရဲ့ variable တွေ ပါဝင်နေတာ ဖြစ်ပါတယ်။

အဓိက အချက်များ

အထဲကနေ အပြင်ကိုပဲ မြင်ရတယ်: Function အငယ်လေးတွေက သူတို့ကို ဝန်းရံထားတဲ့ အပြင်ဘက်
(Parent) scope တွေကို လှမ်းမြင်နိုင်ပေမဲ့၊ အပြင်ဘက်က function ကတော့ အထဲက function ထဲက variable
တွေကို လှမ်းမမြင်နိုင်ပါဘူး။

Static ဖြစ်တယ်: Function ကို ဘယ်နေရာမှာ "ခေါ်သလဲ" (Call-site) ဆိုတာက အရေးမကြီးပါဘူး။
ဘယ်နေရာမှာ "ကြေညာခဲ့သလဲ" (Definition-site) ဆိုတာကပဲ အရေးကြီးပါတယ်။

Lexical Scoping vs Dynamic Scoping

JavaScript ဟာ Lexical Scoping ကို သုံးပါတယ်။ တချို့ ဘာသာစကားတွေမှာ သုံးတဲ့ Dynamic Scoping နဲ့ မတူပါဘူး။

JavaScript
const x = 10;

function a() {
  console.log(x);
}

function b() {
  const x = 20;
  a(); // x က ဘယ်လောက်ထွက်မလဲ?
}

b(); 
Lexical Scoping (JS): အဖြေက 10 ထွက်ပါမယ်။ ဘာလို့လဲဆိုတော့ a() ကို ကြေညာခဲ့တဲ့ 
နေရာရဲ့ အပြင်ဘက်မှာ x = 10 ပဲ ရှိလို့ပါ။

Dynamic Scoping: အဖြေက 20 ထွက်ပါလိမ့်မယ် (ဘာလို့လဲဆိုတော့ a() ကို ခေါ်လိုက်တဲ့ နေရာမှာ x က 20 ဖြစ်နေလို့ပါ)။ 
ဒါပေမဲ့ JS က ဒါမျိုး အလုပ်မလုပ်ပါဘူး။


Lexical Scoping ကို "မျိုးရိုးဗီဇ" လို မှတ်သားနိုင်ပါတယ်။ သင်ဟာ သင့်မိဘတွေဆီက အမွေ (Variables) တွေကို ရပိုင်ခွင့်ရှိပါတယ်။ 
သင် ဘယ်မြို့ကိုပဲ ရောက်သွားရောက်သွား (Function ကို ဘယ်မှာပဲ ခေါ်ခေါ်)၊ သင့်ရဲ့ မိဘက ဘယ်သူလဲဆိုတာ (Lexical Parent) မပြောင်းလဲတဲ့အတွက် အဲဒီအမွေတွေကို သင် ဆက်ပြီး သုံးစွဲခွင့် ရှိနေမှာ ဖြစ်ပါတယ်။

Closure

JavaScript မှာ Closure  ဆိုတာက Function တစ်ခုဟာ သူ့ရဲ့အပြင်ဘက် scope (outer function scope)
က variable တွေကို သူကိုယ်တိုင်ပြီးဆုံးသွားရင်တောင် မှတ်မိနေပြီး ပြန်သုံးနိုင်တဲ့ စွမ်းရည် ကို ခေါ်တာဖြစ်ပါတယ်. 

ရိုးရှင်းရှင်း ပြောရရင် "Function တစ်ခုက သူ့ကို ဖန်တီးခဲ့တဲ့ ပတ်ဝန်းကျင် (Outer Scope) မှာရှိတဲ့ Variable တွေကို အမြဲတမ်း မှတ်မိနေခြင်း" ကို ခေါ်တာပါ။

ပုံမှန်အားဖြင့် Function တစ်ခုက အလုပ်လုပ်ပြီးသွားရင် သူ့ထဲက variable တွေဟာ memory ထဲကနေ ပျောက်သွားရမှာပါ။
 ဒါပေမဲ့ Closure ကြောင့် အဲဒီ variable တွေကို ဆက်ပြီး သိမ်းထားနိုင်တာ ဖြစ်ပါတယ်။

၁။ Closure ဘယ်လို ဖြစ်ပေါ်လာသလဲ?

Function တစ်ခုအတွင်းမှာ နောက်ထပ် Function တစ်ခု (Inner Function) ကို ထပ်ရေးပြီး အဲဒီ Inner function ကို 
အပြင်ကို return ပြန်ထုတ်လိုက်တဲ့အခါ Closure ဖြစ်ပေါ်လာပါတယ်။

function outerFunction() {
  let outerVariable = "I am outside!";

  function innerFunction() {
    console.log(outerVariable); // innerFunction က outerVariable ကို သုံးနေတယ်
  }

  return innerFunction; // function ကိုပြန်ထုတ်လိုက်တယ်
}

const myClosure = outerFunction();
myClosure(); // Output: "I am outside!"


ဘာဖြစ်သွားတာလဲ?
outerFunction() အလုပ်လုပ်ပြီးဆုံးသွားပေမယ့် myClosure() ကို ခေါ်လိုက်တဲ့အချိန်မှာ outerVariable ရဲ့ တန်ဖိုးကို ဆက်မှတ်မိနေဆဲဖြစ်ပါတယ်. 


အလုပ်လုပ်ပုံ အဆင့်ဆင့် (Execution Context အရ)

Creation: outerFunction ကို ခေါ်လိုက်တဲ့အခါ သူ့အတွက် Memory နေရာတစ်ခု ရလာပါတယ်။

Returning: သူက innerFunction ကို ပြန်ပေးလိုက်တဲ့အခါ အဲဒီ inner function နဲ့အတူ သူ့ရဲ့ 
Scope Chain  ပါ ပါသွားပါတယ်။

Persistence: Closure က count variable ကို Garbage Collector ကနေ မဖျက်ပစ်အောင်
တားဆီးထားလိုက်ပါတယ်။ ဒါကြောင့် counter() ကို ခေါ်တိုင်း count တန်ဖိုးက ဆက်ရှိနေတာပါ။

၄။ သတိထားရန်အချက်
Closures တွေက variable တွေကို memory ထဲမှာ ဆက်သိမ်းထားတဲ့အတွက် အသုံးမလိုဘဲ အများကြီး 
သုံးရင် Memory Leak (Memory နေရာလွတ် မကျန်တော့ခြင်း) ဖြစ်တတ်ပါတယ်။ အလုပ်ပြီးသွားရင် reference
 ကို null ပြန်လုပ်ပေးဖို့ လိုအပ်ရင် လိုအပ်ပါလိမ့်မယ်။

အနှစ်ချုပ် (Analogy)
Closure ဆိုတာ "ကျောပိုးအိတ်" နဲ့ တူပါတယ်။ Function က တစ်နေရာကို ခရီးထွက်သွားတဲ့အခါ 
(Return ပြန်တဲ့အခါ) သူ့အိမ်မှာရှိတဲ့ ပစ္စည်းတွေကို ကျောပိုးအိတ်ထဲ ထည့်ယူသွားသလိုပါပဲ။ အဲဒီ ပစ္စည်းတွေ 
(Variables) ကို သူရောက်တဲ့နေရာတိုင်းမှာ ပြန်ထုတ်သုံးလို့ ရနေတာမျိုး ဖြစ်ပါတယ်။


About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors