6.1 Closure anlayışı
Closure-lar JavaScript-də ən güclü və vacib konsepsiyalardan biridir. Onlar funksiyalara öz leksik mühitini, hətta icra edildikdən sonra da yadda saxlamağa imkan verir. Bu mühazirədə biz closure anlayışını, onun xüsusiyyətlərini nəzərdən keçirəcəyik və onların istifadəsinin müxtəlif nümunələrini təqdim edəcəyik.
JavaScript-də Closure — bu, funksiya və həmin funksiyanın elan edildiyi leksik mühitin birləşməsidir. Closure funksiyaya "yadda saxlamaq" və xarici sahədəki dəyişənlərə və digər funksiyalara, hətta həmin xarici funksiya icra edildikdən sonra belə, daxil olmağa imkan verir.
Closure-ların əsas xüsusiyyətləri:
- Leksik mühit: funksiya elan olunan zaman mövcud olan bütün dəyişənləri, o cümlədən funksiyanın kontekstini əhatə edir.
- Kontekstin saxlanılması: closure olan funksiya, xarici funksiyanın icrası bitdikdən sonra da xarici mühitdəki dəyişənlərə daxil olmağa davam edə bilər.
6.2 Bağlamaların iş prinsiplərinə dair nümunələr
Nümunə 1: Sadə bağlama
Bu nümunədə innerFunction()
dəyişəni outerVariable
öz xarici görünürlük sahəsindən əldə edə bilir, hətta outerFunction()
işləməsini başa vurduqdan sonra belə.
function outerFunction() {
let outerVariable = 'Mən xarici funksiyadanam';
function innerFunction() {
console.log(outerVariable);
}
return innerFunction;
}
const closure = outerFunction();
closure(); // Çıxış: Mən xarici funksiyadanam
Nümunə 2: Bağlama istifadə edərək sayğac
Bu nümunədə counter-funksiya count
dəyişəninin dəyərini saxlayır və hər çağırışda onu artırır.
function createCounter() {
let count = 0;
return function() {
count++;
return count;
};
}
const counter = createCounter();
console.log(counter()); // Çıxış: 1
console.log(counter()); // Çıxış: 2
console.log(counter()); // Çıxış: 3
Nümunə 3: Dövrdə bağlama
Bağlamalar çox vaxt dəyişən dəyərlərini dövrlərdə saxlamaq üçün istifadə olunur.
Bu nümunədə arr
massivindəki hər bir funksiya yaradılış anındakı i
dəyişəninin dəyərini "xatırlayır" let
blok görünürlük sahəsi sayəsində:
function createArrayWithClosures() {
let arr = [];
for (let i = 0; i < 3; i++) {
arr[i] = function() {
console.log(i);
};
}
return arr;
}
const closures = createArrayWithClosures();
closures[0](); // Çıxış: 0
closures[1](); // Çıxış: 1
closures[2](); // Çıxış: 2
6.3 Qapalı funksiyaların mürəkkəb ssenariləri
Misal 1: Funksiyanın qismən tətbiqi (partial application)
Qapalı funksiyalar bəzi arqumentləri sabit saxlamaqla qismən tətbiq olunmuş funksiyalar yaratmağa imkan verir.
Bu nümunədə multiply()
funksiyası sabitləşdirilmiş a
arqumentinə b
arqumentini vurmaqla nəticə qaytaran funksiyanı qaytarır.
function multiply(a) {
return function(b) {
return a * b;
};
}
const double = multiply(2);
console.log(double(5)); // Çıxaracaq: 10
console.log(double(10)); // Çıxaracaq: 20
Misal 2: Verilənlərin gizlədilməsi (data hiding)
Qapalı funksiyalar şəxsi dəyişənlər və metodlar yaratmaq üçün istifadə oluna bilər.
Bu nümunədə _name
və _age
dəyişənləri şəxsi xarakter daşıyır və yalnız obyekt metodları vasitəsilə əlçatandır:
function createPerson(name, age) {
let _name = name;
let _age = age;
return {
getName: function() {
return _name;
},
getAge: function() {
return _age;
},
setName: function(newName) {
_name = newName;
},
setAge: function(newAge) {
_age = newAge;
}
};
}
const person = createPerson('John', 30);
console.log(person.getName()); // Çıxaracaq: John
person.setName('Jane');
console.log(person.getName()); // Çıxaracaq: Jane
console.log(person.getAge()); // Çıxaracaq: 30
Misal 3: Memoizasiya
Memoizasiya — eyni giriş məlumatları üçün yenidən hesablamaların qarşısını almaq məqsədilə funksiyanın nəticələrinin saxlanıldığı optimizasiya texnikasıdır.
Bu nümunədə memoize()
funksiyası fn()
funksiyasının hesablanmış nəticələrinin keşini saxlamaq üçün qapalı funksiyadan istifadə edir:
function memoize(fn) {
const cache = {};
return function(...args) {
const key = JSON.stringify(args);
if (cache[key]) {
return cache[key];
}
const result = fn(...args);
cache[key] = result;
return result;
};
}
function slowFunction(num) {
console.log('Hesablanır...');
return num * 2;
}
const memoizedFunction = memoize(slowFunction);
console.log(memoizedFunction(5)); // Çıxaracaq: Hesablanır... 10
console.log(memoizedFunction(5)); // Çıxaracaq: 10 (nəticə keşdən alındı)
GO TO FULL VERSION