01 Arrow funksiyalar
Arrow funksiyalar (ox funksiyaları) ES6 ilə JavaScript-ə əlavə edilmiş daha qısa funksiya sintaksisidir. Bu sintaksis kodu daha oxunaqlı və yazılması daha asan edir, xüsusilə də qısa funksiyalar üçün.
Əsas sintaksis
Arrow funksiya ənənəvi funksiya sintaksisinə alternativ təqdim edir:
// Ənənəvi funksiya
function add(a, b) {
return a + b;
}
// Arrow funksiya
const add = (a, b) => {
return a + b;
};
console.log(add(5, 3)); // 8İmplicit return (gizli qaytarma)
Arrow funksiyaların ən güclü xüsusiyyətlərindən biri implicit return-dur. Əgər funksiya yalnız bir ifadə qaytarırsa, figürlü mötərizə və return açar sözünü buraxmaq olar:
// Explicit return
const multiply = (a, b) => {
return a * b;
};
// İmplicit return (eyni nəticə)
const multiply = (a, b) => a * b;
console.log(multiply(4, 5)); // 20
// Array metodlarında istifadə
const numbers = [1, 2, 3, 4, 5];
const doubled = numbers.map(n => n * 2);
console.log(doubled); // [2, 4, 6, 8, 10]
// Obyekt qaytarma (mötərizə lazımdır)
const createUser = (name, age) => ({ name, age });
console.log(createUser("Ali", 25)); // { name: 'Ali', age: 25 }Arrow funksiya variantları
() => {...}- Parametrsiz funksiyax => {...}- Tək parametrli funksiya (mötərizə lazım deyil)(x, y) => {...}- Çox parametrli funksiyax => x * 2- İmplicit return ilə bir sətirli funksiya() => ({ key: 'value' })- Obyekt qaytaran funksiya
// Parametrsiz
const greet = () => console.log("Salam!");
greet(); // Salam!
// Tək parametr (mötərizə lazım deyil)
const square = x => x * x;
console.log(square(5)); // 25
// Çox parametr
const sum = (a, b, c) => a + b + c;
console.log(sum(1, 2, 3)); // 6
// Çox sətirli funksiya body
const processData = (data) => {
const filtered = data.filter(x => x > 0);
const doubled = filtered.map(x => x * 2);
return doubled;
};
// Obyekt qaytarma
const createPoint = (x, y) => ({ x, y });
console.log(createPoint(10, 20)); // { x: 10, y: 20 }Ənənəvi funksiyalardan fərqləri
- Arrow funksiyaların özlərinin 'this' konteksti yoxdur - leksik 'this' istifadə edirlər
- 'arguments' obyekti yoxdur (əvəzinə rest parametrlər istifadə edin)
- Constructor kimi istifadə edilə bilməz (new ilə çağırıla bilməz)
- 'prototype' property-si yoxdur
Arrow funksiyaları nə vaxt istifadə etməli
Arrow funksiyalar hər yerdə istifadə oluna bilməz. Düzgün istifadə hallarını bilmək vacibdir:
✅ İstifadə etmək tövsiyə olunur
- Qısa callback funksiyalar (map, filter, forEach və s.)
- Bir sətirli sadə funksiyalar
- Leksik 'this' lazım olan hallar (parent scope-un 'this'-ini istifadə etmək)
- Array metodlarında və funksional proqramlaşdırmada
❌ İstifadə etməmək tövsiyə olunur
- Obyekt metodları kimi (öz 'this' konteksti lazımdır)
- Constructor funksiyalar (new ilə çağırılacaq)
- 'arguments' obyektinə ehtiyac olan hallar
02 Function expressions və declarations
JavaScript-də funksiya yaratmağın iki əsas yolu var: function declarations və function expressions. Bunları nə vaxt istifadə etməyi bilmək vacibdir.
Function declaration (funksiya bəyannaməsi)
Function declaration 'function' açar sözü ilə başlayır və hoisting-ə məruz qalır. Bu funksiya bəyannamə formasıdır və JavaScript-də ən çox istifadə olunan funksiya yaratma üsuludur:
// Function declaration
function greet(name) {
return "Salam, " + name + "!";
}
console.log(greet("Ayşə")); // Salam, Ayşə!
// Hoisting işləyir
sayHello(); // İşləyir!
function sayHello() {
console.log("Hello!");
}Function declaration xüsusiyyətləri:
- 'function' açar sözü ilə başlayır və funksiyaya ad verilməlidir
- Hoisting-ə məruz qalır - bəyan olunmamışdan əvvəl çağırıla bilər
- Global və ya funksiya scope-unda təyin oluna bilər, amma block scope-a tabe deyil (strict mode-da fərqlidir)
- Kodun strukturunu aydınlaşdırır və oxunmasını asanlaşdırır
Function expression (funksiya ifadəsi)
Function expression funksiya yaradır və onu dəyişənə, obyekt property-sinə və ya başqa yerdə istifadə etmək üçün mənimsədir. Bu, funksiyanı dəyər kimi istifadə etməyə imkan verir:
// Function expression
const greet = function(name) {
return "Salam, " + name + "!";
};
console.log(greet("Ayşə")); // Salam, Ayşə!
// Arrow function expression
const greetArrow = (name) => "Salam, " + name + "!";
// Named function expression (rekursiya üçün faydalıdır)
const factorial = function fact(n) {
return n <= 1 ? 1 : n * fact(n - 1);
};Function expression xüsusiyyətləri:
- Funksiya dəyər kimi istifadə olunur və dəyişənə mənimsədilir
- Hoisting-ə məruz qalmır - yalnız təyin olunduqdan sonra istifadə edilə bilər
- Anonim (adsız) və ya named (adlı) ola bilər
- Daha çevik - callback, şərti təyin və s. üçün əlverişlidir
- Arrow funksiya da function expression növüdür
Function expression növləri
JavaScript-də müxtəlif function expression növləri var:
// Anonim function expression
const greet1 = function(name) {
return "Salam, " + name;
};
// Named function expression
const greet2 = function greetFunction(name) {
return "Salam, " + name;
};
// Arrow function expression
const greet3 = (name) => "Salam, " + name;
// IIFE (Dərhal icra olunan funksiya)
(function() {
console.log("Dərhal icra olundum");
})();
console.log(greet1("Əli")); // Salam, Əli
console.log(greet2("Ayşə")); // Salam, Ayşə
console.log(greet3("Vüsal"));// Salam, VüsalƏtraflı müqayisə
Hoisting fərqi
Function declarations bütün kod icra olunmamışdan əvvəl yuxarı qaldırılır (hoisted), function expressions isə yox:
// ✅ Function declaration işləyir
console.log(add(2, 3)); // 5
function add(a, b) {
return a + b;
}
// ❌ Function expression işləməz
console.log(multiply(2, 3)); // ReferenceError
const multiply = (a, b) => a * b;Function declaration-lar JavaScript mühərrikinin kod icra etməyə başlamazdan əvvəl yaddaşa yerləşdirildiyinə görə (hoisting), bəyan olunmamışdan əvvəl çağırıla bilir. Function expression-lar isə yalnız kod həmin sətirə çatdıqdan sonra mövcud olur.
Scope fərqi
Function declarations və function expressions scope-a fərqli şəkildə tabe olur:
// Block içərisində funksiya təyini
if (true) {
// Function declaration
function blockFunction() {
return "Block function";
}
// Function expression
const blockExpression = function() {
return "Block expression";
};
}
// Function declaration block xaricindən əlçatandır (non-strict mode)
console.log(blockFunction()); // İşləyir
// Function expression block xaricindən əlçatan deyil
// console.log(blockExpression()); // ReferenceError
// Strict mode-da function declaration da block scope-a tabe olurNə vaxt hansını istifadə etməli
Function declaration istifadə edin
Əsas, yenidən istifadə olunan və proqramın strukturunu təşkil edən funksiyalar üçün:
- Modulun və ya faylın əsas funksiyaları üçün
- Public API funksiyaları üçün
- Kodun oxunmasını asanlaşdırmaq üçün (funksiya adı aydın görünür)
Function expression istifadə edin
Dinamik, şərti və ya bir dəfəlik istifadə olunan funksiyalar üçün:
- Callback funksiyalar kimi (event handlers, array metodları)
- Şərti funksiya təyini (if-else blokları içərisində)
- Funksiyaları digər funksiyalardan qaytarmaq
- IIFE (Immediately Invoked Function Expression) yaratmaq
Praktik nümunələr
Real dünya ssenarilərində function declaration və function expression-ların istifadəsi:
// Ssenari 1: Əsas utility funksiya (declaration)
function calculateTax(income) {
return income * 0.2;
}
// Ssenari 2: Obyektdə metodlar (expression)
const handlers = {
click: function() { console.log("Clicked"); },
hover: function() { console.log("Hovered"); },
submit: function() { console.log("Submitted"); }
};
// Ssenari 3: Loop-da funksiyalar yaratmaq (expression)
const operations = [];
for (let i = 0; i < 3; i++) {
operations.push(function() {
return i * 2;
});
}
// Ssenari 4: Şərti funksiya təyini (expression)
function getOperation(type) {
if (type === 'double') {
return function(x) { return x * 2; };
} else if (type === 'triple') {
return function(x) { return x * 3; };
}
}
const doubler = getOperation('double');
console.log(doubler(5)); // 1003 First-class citizens kimi funksiyalar
JavaScript-də funksiyalar first-class citizens (birinci dərəcəli vətəndaşlar) hesab olunur. Bu o deməkdir ki, funksiyalar digər data tipləri kimi eyni şəkildə istifadə oluna bilər.
First-class imkanlar
1. Dəyişənlərə mənimsətmə
Funksiyaları dəyişənlərə mənimsətmək mümkündür:
// Funksiya dəyişənə mənimsədilir
const greet = function(name) {
return "Salam, " + name;
};
const sayHello = greet; // Funksiya başqa dəyişənə mənimsədilir
console.log(sayHello("Əli")); // Salam, Əli2. Arqument kimi ötürmə
Funksiyaları digər funksiyalara arqument kimi ötürmək mümkündür:
// Funksiya digər funksiyaya arqument kimi ötürülür
function repeat(fn, times) {
for (let i = 0; i < times; i++) {
fn(i);
}
}
function printNumber(num) {
console.log("Nömrə:", num);
}
repeat(printNumber, 3);
// Nömrə: 0
// Nömrə: 1
// Nömrə: 23. Funksiyalardan qaytarma
Funksiya digər funksiyanı qaytara bilər:
// Funksiya başqa funksiya qaytarır
function createMultiplier(multiplier) {
return function(number) {
return number * multiplier;
};
}
const double = createMultiplier(2);
const triple = createMultiplier(3);
console.log(double(5)); // 10
console.log(triple(5)); // 154. Data strukturlarında saxlama
Funksiyaları array-lərdə, obyektlərdə və digər data strukturlarında saxlamaq mümkündür:
// Array-də funksiyalar
const operations = [
(x) => x + 1,
(x) => x * 2,
(x) => x - 3
];
let result = 5;
operations.forEach(op => {
result = op(result);
console.log(result);
});
// 6, 12, 9
// Obyektdə funksiyalar
const calculator = {
add: (a, b) => a + b,
subtract: (a, b) => a - b,
multiply: (a, b) => a * b,
divide: (a, b) => a / b
};
console.log(calculator.add(10, 5)); // 15
console.log(calculator.multiply(4, 3)); // 1204 Higher-order funksiyalar
Higher-order funksiyalar JavaScript-in ən güclü xüsusiyyətlərindən biridir. Bu funksiyalar funksional proqramlaşdırmanın əsasını təşkil edir.
Funksiya qəbul edən higher-order funksiyalar
Higher-order funksiya başqa funksiyanı parametr kimi qəbul edə və istədiyinə görə istifadə edə bilər:
// Funksiya qəbul edən higher-order funksiya
function processArray(arr, callback) {
const result = [];
for (let i = 0; i < arr.length; i++) {
result.push(callback(arr[i]));
}
return result;
}
const numbers = [1, 2, 3, 4, 5];
// İki dəfə artırmaq
const doubled = processArray(numbers, x => x * 2);
console.log(doubled); // [2, 4, 6, 8, 10]
// Kvadratını almaq
const squared = processArray(numbers, x => x * x);
console.log(squared); // [1, 4, 9, 16, 25]Funksiya qaytaran higher-order funksiyalar
Funksiya başqa funksiya yaradıb qaytara bilər:
// Funksiya qaytaran higher-order funksiya
function createGreeting(greeting) {
return function(name) {
return greeting + ", " + name + "!";
};
}
const sayHello = createGreeting("Salam");
const sayHi = createGreeting("Salam");
const sayGoodbye = createGreeting("Sağ ol");
console.log(sayHello("Əli")); // Salam, Əli!
console.log(sayHi("Ayşə")); // Salam, Ayşə!
console.log(sayGoodbye("Vüsal")); // Sağ ol, Vüsal!Daxili higher-order funksiyalar
JavaScript-də bir çox daxili higher-order funksiya var (növbəti dərslərdə daha ətraflı öyrənəcəksiniz):
const numbers = [1, 2, 3, 4, 5];
// map - hər elementi transform edir
const doubled = numbers.map(n => n * 2);
console.log(doubled); // [2, 4, 6, 8, 10]
// filter - şərtə uyğun elementləri filtrlər
const evens = numbers.filter(n => n % 2 === 0);
console.log(evens); // [2, 4]
// reduce - elementləri bir dəyərə endirger
const sum = numbers.reduce((acc, n) => acc + n, 0);
console.log(sum); // 15
// forEach - hər element üzərində əməliyyat edir
numbers.forEach(n => console.log(n * n));05 Callback funksiyalar
Callback funksiya digər funksiyanın içərisində çağırılmaq üçün arqument kimi ötürülən funksiyadır. Callback-lər JavaScript-də asinxron proqramlaşdırmanın əsasını təşkil edir.
Sinxron callback-lər
Sinxron callback-lər dərhal icra olunur:
// Sinxron callback
const numbers = [1, 2, 3, 4, 5];
numbers.forEach(function(num) {
console.log(num * 2);
});
// 2, 4, 6, 8, 10
// Öz callback funksiyamız
function processNumbers(arr, callback) {
for (let i = 0; i < arr.length; i++) {
callback(arr[i], i);
}
}
processNumbers([10, 20, 30], (num, index) => {
console.log(`İndeks ${index}: ${num}`);
});Asinxron callback-lər
Asinxron callback-lər gələcəkdə müəyyən bir zamanda icra olunur:
// Asinxron callback
console.log("Başlanğıc");
setTimeout(function() {
console.log("2 saniyə sonra");
}, 2000);
console.log("Son");
// Çıxış: Başlanğıc → Son → 2 saniyə sonra
// Kompleks asinxron əməliyyat
function fetchData(callback) {
setTimeout(() => {
const data = { id: 1, name: "İstifadəçi" };
callback(data);
}, 1000);
}
fetchData((data) => {
console.log("Məlumat alındı:", data);
});Callback best practices
- Callback funksiyalara aydın adlar verin
- Callback hell-dən (çox iç-içə callback-lər) qaçın
- Error handling əlavə edin
- Mümkünsə arrow funksiyalardan istifadə edin
06 Anonim funksiyalar
Anonim funksiyalar adı olmayan funksiyalardır. Bunlar adətən bir dəfə istifadə olunan və ya dərhal ötürülən funksiyalar üçün istifadə olunur.
Anonim funksiya nümunələri
Anonim funksiyaların müxtəlif istifadə yolları:
// Array metodlarında
const numbers = [1, 2, 3, 4, 5];
const doubled = numbers.map(function(n) {
return n * 2;
});
// Arrow funksiya formasında
const tripled = numbers.map(n => n * 3);
// Event handler kimi
button.addEventListener('click', function() {
console.log("Düyməyə kliklənd!");
});
// setTimeout-da
setTimeout(function() {
console.log("Salam!");
}, 1000);
// IIFE kimi
(function() {
const message = "Bu private-dır";
console.log(message);
})();Nə vaxt istifadə etməli
✅ Anonim funksiya istifadəsi məqsədəuyğundur
- Callback kimi istifadə edərkən
- Bir dəfəlik əməliyyatlar üçün
- Qısa və sadə funksiyalar üçün
❌ Anonim funksiya istifadəsi məqsədəuyğun deyil
- Kompleks funksiyalar üçün (debugging çətin olur)
- Yenidən istifadə olunacaq funksiyalar üçün
- Rekursiv funksiyalar üçün
07 Rest parametrlər
Rest parametrlər (... sintaksis) funksiyanın qeyri-müəyyən sayda arqument qəbul etməsinə imkan verir. Bütün arqumentlər bir array-ə yığılır.
Əsas istifadə
Rest parametrlərlə istənilən sayda arqument qəbul edən funksiya yarada bilərik:
// Rest parametrlər istənilən sayda arqument qəbul edir
function sum(...numbers) {
let total = 0;
for (let num of numbers) {
total += num;
}
return total;
}
console.log(sum(1, 2, 3)); // 6
console.log(sum(1, 2, 3, 4, 5)); // 15
console.log(sum(10, 20)); // 30
// Arrow funksiyada rest parametrlər
const multiply = (...nums) => nums.reduce((acc, n) => acc * n, 1);
console.log(multiply(2, 3, 4)); // 24Named parametrlərlə birlikdə istifadə
Rest parametrlər digər parametrlərlə birlikdə istifadə oluna bilər, amma həmişə sonuncu parametr olmalıdır:
// İlk parametr ayrıca, qalanları array-də
function greet(greeting, ...names) {
return names.map(name => `${greeting}, ${name}!`).join('\n');
}
console.log(greet("Salam", "Əli", "Ayşə", "Vüsal"));
// Salam, Əli!\nSalam, Ayşə!\nSalam, Vüsal!
// İlk arqument multiplier, qalanları çarpılacaq ədədlər
function multiply(multiplier, ...numbers) {
return numbers.map(n => n * multiplier);
}
console.log(multiply(2, 1, 2, 3, 4)); // [2, 4, 6, 8]Rest parametr qaydaları
- Rest parametr həmişə funksiyada sonuncu parametr olmalıdır
- Funksiyanın yalnız bir rest parametri ola bilər
- Rest parametr həqiqi array-dir (Array metodları istifadə edə bilərsiniz)
- Rest parametr 'arguments' obyektindən fərqlidir - həqiqi array-dir
08 Spread operator funksiyalarda
Spread operator (...) array və ya iterable-ı ayrı-ayrı elementlərə açır. Funksiya çağırışlarında çox faydalıdır.
Funksiya çağırışlarında array açma
Spread operator ilə array elementlərini funksiya arqumentləri kimi ötürmək olar:
// Array-imiz var
const numbers = [5, 2, 8, 1, 9];
// Spread olmadan (səhv)
console.log(Math.max(numbers)); // NaN (array ötürülür, ədəd deyil)
// Spread ilə (düzgün)
console.log(Math.max(...numbers)); // 9
// Başqa nümunə
function greet(firstName, lastName) {
console.log(`Salam, ${firstName} ${lastName}`);
}
const names = ["Əli", "Məmmədov"];
greet(...names); // Salam, Əli MəmmədovRest və spread birlikdə
Rest parametrləri və spread operatoru birlikdə güclü pattern-lər yaradır:
// Rest qəbul edir, spread göndərir
function sum(...numbers) {
return numbers.reduce((acc, n) => acc + n, 0);
}
const nums1 = [1, 2, 3];
const nums2 = [4, 5, 6];
console.log(sum(...nums1)); // 6
console.log(sum(...nums1, ...nums2)); // 21
console.log(sum(10, ...nums1, 20)); // 36Praktik istifadə nümunələri
// Çoxsaylı array-ları birləşdirmək
function combineArrays(...arrays) {
return [].concat(...arrays);
}
const result = combineArrays([1, 2], [3, 4], [5, 6]);
console.log(result); // [1, 2, 3, 4, 5, 6]
// Flexible logging funksiyası
function log(level, ...messages) {
console.log(`[${level}]`, ...messages);
}
log("INFO", "Əməliyyat", "uğurla", "tamamlandı");
// [INFO] Əməliyyat uğurla tamamlandı09 Müasir kontekstdə IIFE
IIFE (Immediately Invoked Function Expression - Dərhal İcra Olunan Funksiya İfadəsi) yaradıldığı anda icra olunan funksiyadır. ES6-dan əvvəl çox istifadə olunsa da, indi alternativləri var.
IIFE sintaksisi
IIFE yaratmağın bir neçə yolu var:
// Ənənəvi IIFE
(function() {
console.log("Dərhal icra olundum!");
})();
// Arrow funksiya ilə IIFE
(() => {
console.log("Arrow ilə IIFE");
})();
// Parametrlə IIFE
(function(name) {
console.log("Salam, " + name);
})("Dünya");
// Dəyər qaytaran IIFE
const result = (function() {
const x = 10;
const y = 20;
return x + y;
})();
console.log(result); // 30Müasir alternativlər
ES6 ilə IIFE-nin bir çox istifadə hallarını əvəz edən yeni xüsusiyyətlər əlavə olundu:
// Köhnə üsul: IIFE ilə private scope
(function() {
var privateVar = "private";
console.log(privateVar);
})();
// Müasir üsul: Block scope ilə
{
let privateVar = "private";
console.log(privateVar);
}
// Köhnə module pattern (IIFE ilə)
const counter = (function() {
let count = 0;
return {
increment: () => ++count,
getCount: () => count
};
})();
// Müasir module (ES6 modules ilə)
let count = 0;
export const increment = () => ++count;
export const getCount = () => count;IIFE-ni hələ də nə vaxt istifadə etməli
- Köhnə kodla işləyərkən və ya köhnə brauzerlərə dəstək verərkən
- Module sistemləri olmayan mühitlərdə
- Dərhal icra olunan initialization kodu üçün
- Loop-da closure yaratmaq üçün (amma let daha yaxşı seçimdir)
// İnicialization pattern ilə IIFE
const app = (function() {
// Private dəyişənlər
let config = {
apiUrl: 'https://api.example.com',
timeout: 5000
};
let cache = {};
// Public interface
return {
init: function() {
console.log("Tətbiq başladı");
},
getConfig: function(key) {
return config[key];
},
setCache: function(key, value) {
cache[key] = value;
}
};
})();
app.init(); // Tətbiq başladıXülasə
Təklifiniz var, səhv və ya xəta tapdınız? Zəhmət olmasa bizimlə əlaqə saxlayın.