IlmHamroh
JavaScript Full-stack/8-qism. JavaScript asoslari41/61-dars13 daqiqa
Mundarija (26)

JavaScript arrow funksiyalar va function expression: funksiya — qiymat

Qisqacha: Function expression — funksiyani o'zgaruvchiga qiymat sifatida saqlash: const qosh = function (a, b) { return a + b; };. Arrow funksiya — shuning qisqa yozuvi: const qosh = (a, b) => a + b;. Arrow'da => dan keyin bitta ifoda bo'lsa, natija returnsiz qaytadi.

Bu darsda

  • Funksiyani o'zgaruvchiga saqlay olasiz (function expression).
  • Function declaration va function expression farqini bilasiz.
  • Arrow funksiyani barcha shakllarda yoza va o'qiy olasiz.
  • Yashirin return qachon ishlashini va qachon ishlamasligini bilasiz.
  • Qaysi holatda qaysi shaklni tanlashni bilasiz.

Oldin bilishingiz kerak: return va erta qaytish, Parametrlar va default qiymatlar, let va const, Ternary operatori.

1. Nega bu kerak?

O'tgan darsda funksiyadan natija qaytarishni o'rgandik. Hozirgacha funksiyani faqat bitta usulda yozdik: function nomi() { ... }. Lekin GitHub'dagi loyihalarni yoki React kodini ochsangiz, boshqacha narsalarni ko'rasiz:

js
const kvadrat = (son) => son * son;
const salom = () => "Salom!";

Birinchi ko'rganda bu g'alati belgilar to'plamiga o'xshaydi. Aslida bu ham funksiya — faqat qisqa yozilgan. Zamonaviy JavaScript kodining katta qismi aynan shunday yoziladi.

Bu darsda ikki g'oyani o'rganamiz:

  1. Funksiya — son yoki satr kabi qiymat. Uni o'zgaruvchiga saqlash mumkin.
  2. Qisqa funksiyalarni => bilan bir qatorda yozish mumkin.

Birinchi g'oya keyinchalik funksiyani boshqa funksiyaga berish imkonini ochadi. Ikkinchisi kodni ancha ixcham qiladi.

2. Function expression

2.1 Funksiya o'zgaruvchida

let va const darsida o'zgaruvchini qiymatga yopishtirilgan yorliq deb atagan edik: const narx = 5000;. JavaScript'da funksiya ham qiymat. Demak, uni ham o'zgaruvchiga saqlash mumkin:

js
const salomlash = function (ism) {
  return `Salom, ${ism}!`;
};

console.log(salomlash("Ali")); // Salom, Ali!

Function expression (funksiya ifodasi) — ifoda ichida yozilgan funksiya. Ko'pincha u o'zgaruvchiga tayinlanadi. Ifoda — qiymat beradigan kod bo'lagi: 5000 qiymat beradi, 2 + 3 ham. function (ism) { ... } ham qiymat beradi — funksiyaning o'zini.

Oddiy e'londan (function declaration) uchta farqi bor:

  • function so'zidan keyin nom yo'q. Bunday funksiya anonim (nomsiz) deyiladi. Uning nomi — o'zgaruvchi nomi.
  • Oxirida ; turibdi, chunki bu const x = ...; ko'rsatmasi.
  • Chaqirish esa o'zgarmadi: salomlash("Ali").

2.2 Funksiya qanday turdagi qiymat?

js
const salomlash = function () {
  return "Salom!";
};

console.log(typeof salomlash); // function
console.log(salomlash); // [Function: salomlash]

typeof funksiya uchun "function" qaytaradi. console.log esa funksiyaning o'zini ko'rsatdi. Qarang: funksiya anonim edi, lekin JavaScript unga o'zgaruvchi nomini avtomatik berdi — salomlash.

Maslahat: function so'zidan keyin nom yozsa ham bo'ladi: const f = function hisobla() {}. Bu nomli function expression deyiladi. U maxsus holatlarda kerak bo'ladi — IIFE darsida ko'ramiz.

2.3 Farq: e'londan oldin chaqirish

Funksiya e'lon qilish darsida function bilan yozilgan funksiyani e'londan oldin ham chaqirish mumkinligini ko'rgan edik. Function expression bilan bu ishlamaydi:

js
console.log(chegirma(100000));

const chegirma = function (narx) {
  return narx * 0.1;
};
text
ReferenceError: Cannot access 'chegirma' before initialization

Tarjimasi: "chegirmaga u tayyor bo'lishidan oldin murojaat qilib bo'lmaydi". const o'zgaruvchi o'z qatori bajarilmaguncha ishlatilmaydi. Funksiya ham faqat shu qatorga yetib kelinganda "tug'iladi". Buning ichki sababini hoisting darsida ko'ramiz.

Declaration Expression
Yozilishi function nomi() {} const nomi = function () {};
E'londan oldin chaqirish Mumkin Mumkin emas
Oxirida ; Yo'q Bor

Yana bir foydali farq bor. Funksiya e'lon qilish darsida aytganimizdek, bir xil nomli ikki declaration xato bermaydi — ikkinchisi birinchisini jimgina bosib ketadi. const bilan esa JavaScript darhol ogohlantiradi: SyntaxError: Identifier 'salom' has already been declared.

Tekshirib ko'ring: Qaysi kod ishlaydi, qaysi biri xato beradi?

js
// A
console.log(ikki(5));
function ikki(x) { return x * 2; }

// B
console.log(uch(5));
const uch = function (x) { return x * 3; };
Javob

A ishlaydi va 10 chiqaradi — function bilan e'lon qilingan funksiyani oldindan chaqirish mumkin. B esa ReferenceError: Cannot access 'uch' before initialization beradi, chunki const uch qatori hali bajarilmagan.

3. Arrow funksiyalar

3.1 Function expression'dan arrow'ga

Function expression'ni qisqartirib, arrow funksiyaga aylantiramiz. Qadamma-qadam:

js
// 1. Function expression
const kvadrat = function (son) {
  return son * son;
};

// 2. `function` so'zini olib, qavsdan keyin => qo'yamiz
const kvadrat = (son) => {
  return son * son;
};

// 3. Tanada faqat bitta return bo'lsa — {} va return tushadi
const kvadrat = (son) => son * son;

Uchalasi ham bir xil ishlaydi. Oxirgisini sinab ko'ramiz:

js
const kvadrat = (son) => son * son;

console.log(kvadrat(5)); // 25
console.log(kvadrat(12)); // 144

Arrow funksiya (arrow function) — => belgisi bilan yoziladigan qisqa funksiya. => o'qqa (strelkaga) o'xshaydi, nomi ham shundan. => ni "shunga aylanadi" deb o'qing: (son) => son * son — "son kiradi, son * son chiqadi".

3.2 Parametrlar soniga qarab shakllar

js
const salom = () => "Salom!";
const ikkilantir = (x) => x * 2;
const uchlantir = x => x * 3;
const qosh = (a, b) => a + b;
const mehmon = (ism = "Mehmon") => `Salom, ${ism}!`;

console.log(salom()); // Salom!
console.log(ikkilantir(4)); // 8
console.log(uchlantir(4)); // 12
console.log(qosh(2, 3)); // 5
console.log(mehmon()); // Salom, Mehmon!
Parametrlar Yozilishi Qavs
Yo'q () => ... Bo'sh qavs shart
Bitta (x) => ... yoki x => ... Ixtiyoriy
Ikki va ko'proq (a, b) => ... Shart
Default bilan (x = 1) => ... Shart

Maslahat: Bitta parametrda qavsni tashlab ketish mumkin, lekin ko'p jamoalar har doim qavs qo'yadi: (x) => .... Prettier (kodni avtomatik formatlovchi vosita) ham standart holatda shunday qiladi. Bu kursda ham shu uslubda yozamiz.

3.3 Ifodali tana va blokli tana

Arrow funksiya tanasi ikki xil bo'ladi.

Ifodali tana — => dan keyin bitta ifoda keladi. Uning natijasi avtomatik qaytariladi. Bu yashirin qaytarish (implicit return) deyiladi — return yozilmaydi, lekin u bor.

Blokli tana — => dan keyin { } keladi. Ichida bir necha qator, if, sikl bo'lishi mumkin. Lekin natijani qaytarish uchun return shart.

js
const taksiNarxi = (km, tarif = 2500) => {
  const narx = km * tarif;
  if (narx < 8000) {
    return 8000;
  }
  return narx;
};

console.log(taksiNarxi(2)); // 8000
console.log(taksiNarxi(10)); // 25000

Blokli tanada hammasi oddiy funksiyadagidek: o'zgaruvchilar, erta qaytish, bir nechta return.

Eslab qolish uchun oddiy qoida:

  • => dan keyin { bormi — return yozing.
  • { yo'qmi — natija o'zi qaytadi.

Tekshirib ko'ring: Konsolda nima chiqadi?

js
const kopaytir = (a, b) => {
  a * b;
};
console.log(kopaytir(2, 3));
Javob

undefined. => dan keyin { bor — demak bu blokli tana va unda yashirin qaytarish ishlamaydi. a * b hisoblandi, lekin qaytarilmadi. To'g'risi: (a, b) => a * b yoki { return a * b; }.

3.4 Uzun ifodani bir necha qatorga bo'lish

Ifoda bir qatorga sig'masa, uni oddiy qavsga olib, bir necha qatorga bo'lish mumkin. Yashirin qaytarish baribir ishlaydi:

js
const chekQatori = (taom, narx, soni) => (
  `${taom}: ${soni} x ${narx} = ${narx * soni} so'm`
);

console.log(chekQatori("Lag'mon", 30000, 2));

Konsolda:

text
Lag'mon: 2 x 30000 = 60000 so'm

Ifodali tanaga ternary operatori juda mos keladi. Chunki u ham bitta ifoda, if esa ifoda emas:

js
const natija = (ball) => (ball >= 55 ? "o'tdi" : "yiqildi");

console.log(natija(70)); // o'tdi
console.log(natija(40)); // yiqildi

O'zingiz to'ldiring: const yarmi = (x) => x / 2; bo'lsa, yarmi(10) [:5] qaytaradi. const f = (x) => { x / 2; }; bo'lsa, f(10) [:undefined] qaytaradi.

3.5 Obyekt qaytarishdagi qavs

Diqqat: Keyinroq arrow'dan obyekt qaytarasiz. Obyekt ham { } bilan yoziladi — uni obyektlar darsida o'rganamiz. Muammo shunda: JavaScript => { ni ko'rsa, uni blokli tana deb o'ylaydi. Shuning uchun obyekt qaytarishda uni oddiy qavsga o'rash kerak: () => ({ ism: "Ali" }). Ichidagi ism: "Ali" nima ekanini hozir bilish shart emas. Hozircha bitta qoidani eslab qoling: arrow'dan obyekt qaytarsangiz, uni ( ) ga o'rang.

4. Arrow faqat qisqaligi bilan farq qiladimi?

Yo'q. Arrow funksiya oddiy functiondan yozilishidan tashqari xulqi bilan ham farq qiladi:

  • arguments yo'q. Parametrlar darsida ko'rgan arguments arrow ichida mavjud emas. Hamma argumentlarni yig'ish kerak bo'lsa, rest parametrlar ishlatiladi.
  • E'londan oldin chaqirib bo'lmaydi. Arrow ham constga saqlanadi, shuning uchun function expression kabi ishlaydi.
  • this boshqacha ishlaydi. Arrow'ning yana bir farqi bor — u this bilan bog'liq, buni keyinroq this darsida ko'ramiz.

Hozirgi bilimingiz uchun birinchi ikkitasi yetarli. Uchinchisi obyektlar va metodlarni o'rganganda muhim bo'ladi.

5. Qaysi shaklni tanlash kerak?

Uchala shakl ham to'g'ri. Real kodda hammasi uchraydi. Odatda shunday tanlanadi:

Vaziyat Tavsiya
Katta, mustaqil, nomli funksiya function declaration yoki const + arrow
Bir qatorli qisqa hisob Arrow, ifodali tana
Boshqa funksiyaga beriladigan funksiya Arrow
this kerak bo'lgan metod Oddiy function

Eng muhimi — izchillik. Jamoa bitta uslubni tanlaydi va hamma shunga amal qiladi. Funksiyani boshqa funksiyaga berish (callback) — arrow'ning eng ko'p ishlatiladigan joyi. Uni ikki darsdan keyin o'rganamiz.

Function expression'ning function so'zi bilan yozilgan shakli (const f = function () {}) bugun kamroq uchraydi. Uni ko'pincha arrow almashtirgan. Lekin eski kodda uni albatta ko'rasiz.

6. Ko'p uchraydigan xatolar

6.1 Blokli tanada returnni unutish

js
const qosh = (a, b) => {
  a + b;
};

console.log(qosh(2, 3)); // undefined

Xato chiqmaydi, lekin natija undefined. Bu arrow funksiyalardagi eng ko'p uchraydigan xato. { qo'ydingizmi — return ham yozing.

6.2 => ni yangi qatorga o'tkazish

js
const ikkilantir = (x)
  => x * 2;
text
SyntaxError: Unexpected token '=>'

"Kutilmagan => belgisi". JavaScript (x) dan keyin qator tugaganini ko'rib, uni tugallangan deb o'ylaydi. Keyingi qatordagi => esa "osilib qoladi". Qoida: => parametrlar bilan bitta qatorda tursin.

6.3 Ikki parametrda qavsni unutish

js
const qosh = a, b => a + b;
text
SyntaxError: Missing initializer in const declaration

Xato matni chalkash, keling, tushunamiz. JavaScript vergulni ko'rib, const bilan ikkita o'zgaruvchi e'lon qilinyapti deb o'yladi: qosh = a va b. const o'zgaruvchiga esa qiymat berish shart. Parametrlar bittadan ko'p bo'lsa, qavs majburiy: (a, b) => a + b.

6.4 Nomsiz function ni yolg'iz yozish

js
function (narx) {
  return narx * 0.1;
}
text
SyntaxError: Function statements require a function name

"Funksiya e'loniga nom kerak". Nomsiz funksiya faqat ifoda ichida — masalan, const chegirma = ... o'ng tomonida — yashay oladi. Yolg'iz turgan function esa e'lon hisoblanadi va unga nom shart.

6.5 Bir nomni ikki marta e'lon qilish

js
const salom = () => "Salom!";
const salom = () => "Assalomu alaykum!";
text
SyntaxError: Identifier 'salom' has already been declared

"salom nomi allaqachon e'lon qilingan". Bu xato aslida foydali — declaration'dagi jim "bosib ketish"dan himoya qiladi. Ikkinchi funksiyaga boshqa nom bering yoki birinchisini o'zgartiring.

7. Mashqlar

1-mashq (oson): Uch xil yozuv

Quyidagi funksiyani avval function expression, keyin ifodali tanali arrow ko'rinishida qayta yozing. Har birini 3 bilan chaqirib tekshiring.

js
function kub(son) {
  return son * son * son;
}

console.log(kub(3)); // 27
Yechim
js
const kubA = function (son) {
  return son * son * son;
};

const kubB = (son) => son * son * son;

console.log(kubA(3)); // 27
console.log(kubB(3)); // 27

Bitta faylda bir xil nom ikki marta const bilan e'lon qilinmasligi uchun kubA va kubB deb nomladik.

2-mashq (o'rta): Valyuta kalkulyatori

Ikki arrow funksiya yozing:

  • somga(dollar, kurs = 12800) — dollarni so'mga aylantirib qaytaradi.
  • baho(somda) — summa 1 000 000 so'mdan katta bo'lsa "qimmat", aks holda "arzon" qaytaradi. Ternary ishlating.

So'ng 50 va 100 dollar uchun 640000 so'm — arzon ko'rinishidagi qatorni chiqaring. Kurs taxminiy, faqat mashq uchun.

Yechim
js
const somga = (dollar, kurs = 12800) => dollar * kurs;
const baho = (somda) => (somda > 1000000 ? "qimmat" : "arzon");

const a = somga(50);
const b = somga(100);
console.log(`${a} so'm — ${baho(a)}`);
console.log(`${b} so'm — ${baho(b)}`);

Konsolda:

text
640000 so'm — arzon
1280000 so'm — qimmat

Ikkala funksiya ham ifodali tanali — return kerak bo'lmadi. baho dagi qavslar shart emas, lekin ternary'ni o'qishni osonlashtiradi.

3-mashq (qiyin): Xatolarni toping

Yetkazib berish xizmati narxni shunday hisoblaydi: 5000 so'm + har kilometr uchun 1500 so'm. Quyidagi kodda uchta xato bor. Ularni toping va tuzating — yetkazish(3) 9500 chiqarishi kerak.

js
console.log(yetkazish(3));

const yetkazish = (km)
  => {
  const narx = 5000 + km * 1500;
  narx;
};

Bonus: tuzatilgan funksiyani ifodali tanali bitta qatorga aylantiring.

Yechim

Xatolar:

  1. => yangi qatorda turibdi — SyntaxError. U (km) bilan bitta qatorda bo'lishi kerak.
  2. Blokli tanada return yo'q — funksiya undefined qaytarardi.
  3. Funksiya e'lon qilinishidan oldin chaqirilyapti — const bilan bunday qilib bo'lmaydi.
js
const yetkazish = (km) => {
  const narx = 5000 + km * 1500;
  return narx;
};

console.log(yetkazish(3)); // 9500

Bonus — bitta qatorda:

js
const yetkazish = (km) => 5000 + km * 1500;

console.log(yetkazish(3)); // 9500

JavaScript xatolarni birma-bir ko'rsatadi: avval SyntaxError, uni tuzatsangiz — ReferenceError, keyin esa jim undefined. Shuning uchun tuzatgandan keyin kodni har safar qayta ishga tushiring.

8. Real ishda

Arrow funksiyalar zamonaviy JavaScript'da hamma joyda:

  • React: komponentlar ko'pincha const Tugma = () => { ... }; ko'rinishida yoziladi.
  • Massivlar bilan ishlash: narxlar.map((n) => n * 2) — har bir narxni ikkilantirish. Massivlarni tez orada o'rganamiz, u yerda arrow'lar har qadamda uchraydi.
  • Taymer va hodisalar: setTimeout(() => { ... }, 1000) — bir soniyadan keyin bajariladigan kod.
  • Kod uslubi: ESLint vositasida prefer-arrow-callback qoidasi bor. U boshqa funksiyaga beriladigan funksiyalarni arrow bilan yozishni talab qiladi.

Intervyuda deyarli har doim so'raladi: "Arrow funksiya oddiy funksiyadan nimasi bilan farq qiladi?". Qisqa javob: yozuvi qisqa, yashirin return bor, o'z arguments va thisi yo'q, constda saqlangani uchun e'londan oldin chaqirib bo'lmaydi.

Xulosa

  • Funksiya — qiymat: uni o'zgaruvchiga saqlash mumkin (const f = function () {};).
  • Function expression e'londan oldin chaqirilmaydi, declaration esa chaqiriladi.
  • Arrow — qisqa yozuv: (a, b) => a + b. Parametrsiz — (), bitta parametrda qavs ixtiyoriy.
  • Ifodali tana natijani yashirin qaytaradi. { } bo'lsa — return shart.
  • Obyekt qaytarishda qavs kerak: () => ({ ... }).
  • Arrow'da arguments yo'q va this boshqacha ishlaydi.

Keyingi dars: Scope asoslari: global, funksiya va blok — o'zgaruvchi qayerda ko'rinishini va nega funksiya ichidagi o'zgaruvchi tashqarida "yo'qolishini" o'rganamiz.

Ulashish:Telegram'da

Izohlar (0)

Izoh yozish uchun kiring.

  • Hozircha izoh yo'q. Birinchi bo'ling!
JavaScript arrow funksiyalar va function expression: funksiya — qiymat — IlmHamroh