Funksiyalar bilan chuqur ishlash

Funksiya obyekti, NFE

JavaScript'da funksiya โ€” bu shunchaki chaqiriladigan amal emas, balki to'laqonli obyekt. Uni chaqirish mumkin, lekin ayni paytda unga xossalar qo'shish, undan xossalarni o'qish ham mumkin. Ushbu darsda funksiyaning obyekt sifatidagi tabiatini chuqur o'rganamiz.

Funksiya โ€” bu obyekt

Biz allaqachon funksiyalar chaqiriladigan (callable) qiymatlar ekanligini bilamiz. Ammo JavaScript'da funksiyalar obyekt turiga kiradi. Ularni obyekt sifatida tasavvur qilish qulay: chaqirsa bo'ladigan "harakat qiluvchi obyekt".

Obyekt bo'lgani uchun funksiyaga xossalarni o'qish, qo'shish va o'chirish, uni o'zgaruvchanga uzatish mumkin. Va eng qizig'i โ€” funksiyalarning tayyor, o'rnatilgan (built-in) xossalari ham bor.

Funksiya typeof orqali tekshirilganda "function" deb qaytadi, lekin ichki jihatdan u obyektga asoslangan. Shuning uchun unga nuqta (.) orqali xossalar qo'shish mumkin.

name xossasi

Har bir funksiyaning name xossasi bor โ€” bu uning nomini o'zida saqlaydi. Eng qizig'i, funksiyaga aniq nom berilmagan holatlarda ham JavaScript nomni o'zi "topib beradi" (bu contextual name โ€” kontekstli nom deb ataladi).

name-xossasi.js
// natija shu yerda chiqadi

Ba'zan nomni aniqlashning imkoni yo'q โ€” bunda name bo'sh satr bo'ladi. Masalan, funksiya massiv ichida yaratilsa:

name-bosh.js
// natija shu yerda chiqadi
Obyekt metodlarining ham name xossasi bor. Bu funksiyaning "o'z nomini bilishi" logging (jurnal yozish) va debugging paytida juda foydali.

length xossasi

Yana bir o'rnatilgan xossa โ€” length. U funksiya parametrlari sonini qaytaradi, ammo rest parametri (...args) hisobga olinmaydi.

length-xossasi.js
// natija shu yerda chiqadi

length xossasi ba'zida amaliy ma'noga ega. Masalan, boshqa funksiyalar ustida ishlaydigan funksiyalarda uzatilgan funksiya nechta argument kutishini tekshirish uchun ishlatiladi.

Standart qiymatga ega parametrlar ham lengthdan tashqarida qoladi. Masalan, function f(a, b = 1) {} uchun f.length โ€” 1 bo'ladi, chunki hisob birinchi standart qiymatli parametrda to'xtaydi.

O'z xossalarini qo'shish

Funksiyaga o'zimizning xossalarimizni ham qo'shishimiz mumkin. Bu ba'zan holatni (state) funksiyaning o'zida saqlash uchun qulay yechim beradi.

Quyida counter funksiyasi chaqirilgan sonini o'zining count xossasida saqlaydi:

funksiya-xossasi.js
// natija shu yerda chiqadi
Xossaga berilgan qiymat โ€” bu o'zgaruvchan (variable) emas. counter.count va funksiya ichidagi lokal let count bir-biriga bog'liq emas. Xossa funksiya obyektiga "yopishtirilgan", closure orqali yashiringan o'zgaruvchandan farq qiladi.

Ba'zan closure o'rniga funksiya xossasidan foydalanish afzalroq: xossa tashqaridan ko'rinadi va o'zgartirilishi mumkin. Masalan, hisoblagichni tashqaridan nolga qaytarish oson bo'ladi.

Named Function Expression (NFE)

Named Function Expression (NFE โ€” nomli funksional ifoda) โ€” bu nomi bor Function Expression. Nom faqat funksiya ichida o'ziga murojaat qilish uchun ishlatiladi va tashqarida ko'rinmaydi.

nfe-asosiy.js
// natija shu yerda chiqadi

Bu yerda func nomining ikkita xususiyati bor:

"Nega shunchaki sayHi nomidan foydalanmaymiz?" degan savol tug'iladi. Muammo shundaki, tashqi o'zgaruvchan keyinroq o'zgartirilishi mumkin. Agar sayHi boshqa qiymatga tenglashsa, funksiya o'ziga to'g'ri murojaat qila olmay qoladi:

nfe-himoya.js
// natija shu yerda chiqadi

Agar func o'rniga tashqi sayHi ishlatilganida, sayHi = null bo'lgach ichki chaqiruv "sayHi is not a function" xatoligini bergan bo'lardi. NFE aynan shu muammodan himoya qiladi.

Ichki nom faqat Function Expression uchun ishlaydi. Function Declaration (oddiy function name() {}) uchun alohida "ichki" nom mavjud emas โ€” u yerda oddiy nomning o'zi tashqarida ham, ichkarida ham ishlaydi.

Xulosa