Closure-ները JavaScript-ում.
Published: 2024-01-04 13:09:12

Երբևէ լսե՞լ եք JavaScript-ում closure-ների մասին շատերին այն բարդ ու անհասկանալի է թվում(ինձ թվում է անունից է) բայց մի անհանգստացեք դա այնքան էլ բարդ չէ, որքան թվում  է 

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/2naab2y9bcvld0hf2zss.png)


JavaScript-ում closure-ները նման են տուփի որը պահում է ֆունկցիան և այն միջավայրը որում ֆունկցիան հայտարավել է, այն թույլ է տալիս ֆունկցիային հիշել այն միջավայրը որում այն ստեղծվել է( այդ միջավայրի փոփոխականները): այսինքն javascript ում ֆունկցիան ոչ միայն ունի այն փոփոխականները որոնք հայտարարվել են իր մեջ կամ ստացել է որպես արգումենտ այլ նաև այն scop-ի փոփոխականները որում ֆունկցիան հայտարարել ենք։ շուտով ամեն ինչ ավելի պարզ կդառնա

**_Եկեք պարզենք կախարդանքը պարզ օրինակներով._**

```
let name = 'Dav'
function seyHi(){
	console.log('hello ' + name)
}

seyHi()
//hello Dav
```

այստեղ մենք հայտարարել ենք ֆունկցիա որը օգտագործում է իր ծնող scop ի փոփոխականը (այն scop-ի որում հայտարարվել է) և այդ ֆունկցիան նորմալ աշխատում է և փոփոխականի կախվածության հետ միասին կոչվում է Closure։ այսպիսով ֆունկցիան իր կախվածությունների հետ(այն փոփոխականների որոնք նա օգտագործում է բայց հայտարարված են իրենից դուրս) միասին կոչվում է Closure հայերեն կարող են ասել "փակում" (մի փոքր ծիրծացելի թարգմանություն է բայց այո բառացի այդպես է թարգմանվում)  

նայենք մեկ այլ օրինակ

```
function outerFunction() {
  let outerVariable = "ես դրսում եմ հայտարարված!";

  function innerFunction() {
    console.log(outerVariable);
  }

  return innerFunction;
}

const closureFunction = outerFunction();
closureFunction(); // Output: ես դրսում եմ հայտարարված
```

այստեղ մենք հայտարարել ենք ֆունկցիա outerFunction անունով դրա մեջ outerVariable անունով փոփոխական ու մի ֆունկցիայել innerFunction անունով որը տպում է outerVariable փոփոխականը հետո վերադրաձնում ենք ներսում հայտարարված ֆունցիան՝ innerFunction-ը։
և այո javascript ում հնարավոր է որպես արժեք վերադրաձնել ֆունցիան ու երբ այն ֆունկցիան որը վերադարձնում է տվյալ ֆունկցիան վերագրվում է փոփոխականին կարելի է ասել որ այդ փոփոխականը դառնում է հղում ներսի ֆունկցիայի համար որը հնարավոր է կանչել(եթե չհասկացաք ուղակի նայեք կոդին)

այսպիսով ինչ կատարվեց innerFunction ը օգտագործում է outerVariable-ը որը հայտարարված է իր ծնող ֆունկցիայում և դա հնարավոր է որովհետև innerFunction-ը պահում է outerVariable փոփոխականը(ի շնորիվ Closure-ի)

debugger ում կարող եք նայել closure-ները: նայեք նկարի կոդին և closure-ները
![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/mg8g1g79kcalct8yg9nm.png)


հիմա եկեք մի փոքր բարդացնենք

```
let globalVariable = "ես global scop ում եմ գտնվում"
function outerFunction() {
  let outerVariable = "ես դրսում եմ հայտարարված!";

  function innerFunction() {
    console.log(outerVariable);
    console.log(globalVariable );
  }

  return innerFunction;
}

const closureFunction = outerFunction();
closureFunction(); // Output: "ես դրսում եմ հայտարարված!"							 
                   // Output։ ""ես global scop ում եմ գտնվու 

```

global scop ում ավելացրել եմ փոփոխական globalVariable  անունով ու այն օգտագործել եմ innerFunction ում և ամեն ինչ դեռ աշխատում է ինչի քանի որ outerFunction ը պահում է global scop ի փոփոխականները(քանի որ այդտեղ է հայտարարվել) իսկ innerFunction ը outerFunction-ի մեջ գտնվուղ փոփոխականները ու այդպես "ժառանգաբար" innerFunction ը կարող է օգտագործել global scop ի փոփոխականները։ ի շնորհիվ դրա ֆունկցիաները կորող են իրենց կրող scop ի փոփոխականները օգտագործել նաև իրենց կրող scop ը կրող scop-ում գտնվող փոփոխականները և այդպես մինչև global scop բոլոր փոփոխականները այլ կերպ ասած ինենց scop ից վեր գտնվող բոլոր scop-երի փոփոխականները



եկեք նայենք մեկ այլ օրինակ

```
function f(){

  function k(){
  	var x = 10
		
	}
  k()
  console.log(x)
  
}


f() // Output: ReferenceError: x is not defined"

```

հայտարարել եմ f ֆունկցիա դրա մեջ k անունով ֆունկցիա և k ֆունկցիայի մեջ x անունով փոփոխական իսկ հետո  f() ֆունկցիայում փորձել օգտագործել x ը և ReferenceError: x is not defined" հմմ ինչի։ քանի որ ֆունկցիան պահում է միայն իրեն կրող scop ի փոփոխականները իսկ k ֆունկցիան գտնվում է f ի մեջ այսինքն k ի մեջ հասանելի են f ի փոփոխականները բայց հակառակը ոչ նույն կերպել global scop ում հասանելի չեն f և k ֆունկցիաներում հայտարարված փոփոխականները բայց global scop ի փոփոխականները հասանելի են 2 ֆունկցիաներումել 

իրականում jsvasctipt ի engin-ը ավելի խելացի է և միայն պահում է այն փոփոխականները որոնք ֆունկցիան օգտագործում է և եթե global scop-ում պահենք n անունով փոփոխակամ և չօգտագործենք f ֆունկցիայում f ը չի պահի այդ փոփոխականը

կարող եք նաև տեսահոլովակ նայել նույն թեմայով
{% embed https://youtu.be/bfbYbPTkUmg?si=We8qGCj8C-AV9Gj1 %}