5-bo‘lim
Funksiyalar
Funksiya e'lon qilish usullari, arrow funksiyalar, parametrlar va standart qiymatlar, ko'lam, hoisting va rekursiya.
Ushbu bo‘lim mundarijasi
Funksiya - nom berilgan kod bo'lagi. Bir marta yozib, xohlagancha chaqirasiz.
Uch xil e'lon usuli #
// 1. Funksiya e'loni (declaration)
function kvadrat(son) {
return son * son;
}
// 2. Funksiya ifodasi (expression)
const kub = function (son) {
return son * son * son;
};
// 3. Arrow funksiya
const ikkiBaravar = (son) => son * 2;
console.log("Kvadrat :", kvadrat(5));
console.log("Kub :", kub(3));
console.log("Ikki baravar:", ikkiBaravar(7));
Kvadrat : 25
Kub : 27
Ikki baravar: 14
Hoisting - e'lonlarning ko'tarilishi #
// E'lon qilingan funksiyani oldindan chaqirish mumkin
console.log("Oldindan:", oldinChaqirilgan());
function oldinChaqirilgan() {
return "ishladi";
}
// Ifoda bilan e'lon qilinganini esa mumkin emas
try {
keyinChaqirilgan();
} catch (xato) {
console.log("Xato:", xato.constructor.name);
}
const keyinChaqirilgan = function () {
return "bu ishlamaydi";
};
Oldindan: ishladi
Xato: ReferenceError
Parametrlar va standart qiymatlar #
function salomlash(ism, salom = "Assalomu alaykum") {
return `${salom}, ${ism}!`;
}
console.log(salomlash("Husanboy"));
console.log(salomlash("Nodira", "Salom"));
// Standart qiymat oldingi parametrga tayanishi mumkin
function maydon(eni, boyi = eni) {
return eni * boyi;
}
console.log("Kvadrat :", maydon(5));
console.log("To'rtburchak:", maydon(5, 3));
Assalomu alaykum, Husanboy!
Salom, Nodira!
Kvadrat : 25
To'rtburchak: 15
undefined da ishlaydifunction sinov(qiymat = "standart") {
return qiymat;
}
console.log(sinov()); // "standart"
console.log(sinov(undefined)); // "standart"
console.log(sinov(null)); // null (!)
console.log(sinov(0)); // 0
console.log(sinov("")); // ""
null - bu aniq berilgan qiymat, shuning uchun standart
qiymat ishlamaydi.
Agar null ni ham qamrab olish kerak bo'lsa, ?? ishlating:
function sinov(qiymat) {
const haqiqiy = qiymat ?? "standart";
return haqiqiy;
}
Cheksiz argumentlar - rest #
function yigindi(...sonlar) {
let jami = 0;
for (const son of sonlar) {
jami += son;
}
return jami;
}
console.log(yigindi(1, 2, 3));
console.log(yigindi(10, 20, 30, 40, 50));
console.log(yigindi());
// Birinchisini alohida olish
function birinchiVaQolgani(birinchi, ...qolgani) {
return `birinchi: ${birinchi}, qolgani: [${qolgani}]`;
}
console.log(birinchiVaQolgani("a", "b", "c", "d"));
6
150
0
birinchi: a, qolgani: [b,c,d]
Arrow funksiyalar #
// To'liq shakl
const kvadrat1 = (son) => {
return son * son;
};
// Bitta ifoda bo'lsa - return va qavslar shart emas
const kvadrat2 = son => son * son;
// Bir nechta parametr - qavs kerak
const qoshish = (a, b) => a + b;
// Parametrsiz - bo'sh qavs
const salom = () => "Salom!";
// Obyekt qaytarish - qavs ichiga olinadi
const yaratish = (ism) => ({ ism: ism, faol: true });
console.log(kvadrat1(4), kvadrat2(4));
console.log(qoshish(3, 7));
console.log(salom());
console.log(yaratish("Aziza"));
16 16
10
Salom!
{ ism: 'Aziza', faol: true }
const notogri = () => { ism: "Aziza" };
console.log(notogri()); // undefined
JavaScript { } ni funksiya tanasi deb o'qiydi, obyekt
emas. Ichidagi ism: esa yorliq (label) bo'lib qoladi.
To'g'ri yozish - qavs ichiga olish:
const togri = () => ({ ism: "Aziza" });
Qavslar JavaScript ga "bu ifoda, blok emas" deb aytadi.
this va arrow farqi #
const hisoblagich = {
soni: 0,
oddiy: function () {
return this.soni;
},
strelka: () => {
// arrow o'z this ini yaratmaydi
return typeof this;
}
};
hisoblagich.soni = 42;
console.log("Oddiy funksiya:", hisoblagich.oddiy());
console.log("Arrow funksiya:", hisoblagich.strelka());
Oddiy funksiya: 42
Arrow funksiya: object
Arrow funksiya o'z this iga ega emas - u tashqi ko'lamdan
oladi. Obyekt metodi uchun bu deyarli har doim noto'g'ri:
const talaba = {
ism: "Kamola",
salom: () => `Men ${this.ism}` // this.ism - undefined
};
To'g'ri variantlar:
const talaba = {
ism: "Kamola",
salom() { // qisqa metod sintaksisi
return `Men ${this.ism}`;
}
};
Aksincha, callback ichida arrow aynan foydali - u tashqi
this ni saqlaydi:
class Taymer {
constructor() {
this.soni = 0;
setInterval(() => this.soni++, 1000); // this saqlanadi
}
}
Oddiy function bo'lganda this yo'qolardi va bind(this)
yozishga to'g'ri kelardi.
Ko'lam (scope) #
const global = "global";
function tashqi() {
const tashqiOzgaruvchi = "tashqi";
function ichki() {
const ichkiOzgaruvchi = "ichki";
// uchalasi ham ko'rinadi
return `${global} > ${tashqiOzgaruvchi} > ${ichkiOzgaruvchi}`;
}
return ichki();
}
console.log(tashqi());
// Blok ko'lami
if (true) {
const blokIchida = "blok";
console.log("Blok ichida:", blokIchida);
}
try {
console.log(blokIchida);
} catch (xato) {
console.log("Blokdan tashqarida:", xato.constructor.name);
}
global > tashqi > ichki
Blok ichida: blok
Blokdan tashqarida: ReferenceError
Berkitma (closure) #
function hisoblagichYaratish() {
let soni = 0; // tashqaridan ko'rinmaydi
return {
oshirish() {
soni++;
return soni;
},
qiymat() {
return soni;
}
};
}
const birinchi = hisoblagichYaratish();
const ikkinchi = hisoblagichYaratish();
birinchi.oshirish();
birinchi.oshirish();
ikkinchi.oshirish();
console.log("Birinchi:", birinchi.qiymat());
console.log("Ikkinchi:", ikkinchi.qiymat());
console.log("To'g'ridan-to'g'ri kirish:", birinchi.soni);
Birinchi: 2
Ikkinchi: 1
To'g'ridan-to'g'ri kirish: undefined
Berkitma (closure) - funksiya o'zi yaratilgan ko'lamni "eslab qolishi".
Yuqoridagi misolda soni o'zgaruvchisi:
hisoblagichYaratishtugagandan keyin ham yashaydi;- Faqat qaytarilgan metodlar orqali ko'rinadi;
- Har chaqiruvda yangi nusxasi yaratiladi.
Bu maxfiy holat yaratishning JavaScript dagi klassik usuli -
private kalit so'zisiz.
Amaliy qo'llanishlari:
// 1. Bir marta ishlaydigan funksiya
function birMarta(fn) {
let ishlagan = false;
return function (...args) {
if (!ishlagan) {
ishlagan = true;
return fn(...args);
}
};
}
// 2. Sozlamani "eslab qolish"
function koPaytiruvchi(kopaytma) {
return (son) => son * kopaytma;
}
const uchGa = koPaytiruvchi(3);
Berkitmalar React hook laridan tortib, modul naqshigacha hamma joyda ishlatiladi.
Rekursiya #
function faktorial(n) {
if (n <= 1) {
return 1; // bazaviy holat - to'xtash sharti
}
return n * faktorial(n - 1);
}
console.log("5! =", faktorial(5));
// Ichma-ich obyektni tekislash
function chuqurlik(qiymat) {
if (!Array.isArray(qiymat)) {
return 0;
}
let eng = 0;
for (const element of qiymat) {
eng = Math.max(eng, chuqurlik(element));
}
return eng + 1;
}
console.log("Chuqurlik:", chuqurlik([1, [2, [3, [4]]]]));
5! = 120
Chuqurlik: 4
Rekursiv funksiyada to'xtash sharti bo'lmasa, stek to'lib ketadi:
function cheksiz(n) {
return cheksiz(n - 1); // to'xtash yo'q
}
RangeError: Maximum call stack size exceeded
Node.js da stek odatda ~10 000 chaqiruvga yetadi. Bu:
- Daraxt yoki katalog aylanishi uchun yetarli;
- 100 000 elementli ro'yxat uchun yetarli emas.
Chuqur rekursiya kerak bo'lsa - siklga aylantiring:
function faktorialSikl(n) {
let natija = 1;
for (let i = 2; i <= n; i++) {
natija *= i;
}
return natija;
}
Ba'zi tillar "quyruq rekursiyasi" (tail call) optimizatsiyasini qo'llaydi. JavaScript standartida u bor, lekin brauzerlar deyarli qo'llab-quvvatlamaydi - unga tayanmang.
- Uch usulda ham funksiya e'lon qiling.
- Hoisting farqini
functionvaconstbilan sinang. - Standart qiymatli funksiya yozing.
nulluzatilganda standart qiymat ishlamasligini ko'rsating....restbilan cheksiz argument qabul qiling.- Arrow funksiyada obyekt qaytaring - qavsni unutmang.
- Obyekt metodini arrow bilan yozib,
thismuammosini ko'ring. - Berkitma bilan maxfiy hisoblagich yarating.
- Ikki hisoblagich bir-biriga ta'sir qilmasligini isbotlang.
- Faktorialni rekursiv va siklda yozib taqqoslang.
Xulosa #
- Funksiya e'loni ko'tariladi (hoisting), ifoda esa yo'q.
constbilan e'lon qilingan funksiya TDZ da bo'ladi.- Standart qiymat faqat
undefinedda qo'llanadi,nullda emas. ...restcheksiz argumentni massivga yig'adi.- Arrow funksiyada obyekt qaytarish uchun qavs kerak.
- Arrow o'z
thisiga ega emas - obyekt metodi uchun yaramaydi. - Callback ichida arrow aynan foydali -
thissaqlanadi. - Berkitma funksiyaga o'z ko'lamini eslab qolish imkonini beradi.
- Har chaqiruvda yangi berkitma yaratiladi.
- Rekursiyada bazaviy holat bo'lishi shart.
- Chuqur rekursiya stekni to'ldiradi - siklga aylantiring.
Keyingi bo'limda massivlar bilan ishlashni boshlaymiz.
O‘qish tarixini saqlamoqchimisiz?
Tizimga kirsangiz, tugatgan bo‘limlaringiz saqlanadi va qoldirgan joyingizdan davom etasiz.
Xatolik topdingizmi?
Imlo xatosi, ishlamaydigan kod yoki noto‘g‘ri ma‘lumotni ko‘rsangiz - bizga xabar bering. Har bir xabar administrator tomonidan ko‘rib chiqiladi.