Funksiyalar bilan chuqur ishlash

new Function sintaksisi

Funksiya yaratishning yana bir, kamdan-kam uchraydigan usuli bor โ€” new Function. U funksiyani satr (string) ko'rinishidagi koddan yaratishga imkon beradi. Bu maxsus vaziyatlarda juda foydali.

Sintaksis

Umumiy shakli quyidagicha:

let func = new Function([arg1, arg2, ...argN], funcBody);

Funksiya arg1...argN argumentlari (parametrlar nomlari) va so'nggi funcBody (funksiya tanasi โ€” kod satri) bilan yaratiladi. Barchasi satr ko'rinishida beriladi.

new-function-sum.js
// natija shu yerda chiqadi

Argumentsiz funksiya ham yaratish mumkin โ€” bunda faqat tana beriladi:

new-function-salom.js
// natija shu yerda chiqadi

Asosiy farqi: satrdan kod olish

Oddiy funksiyalar kod yozilish paytida (yozuvchi tomonidan) belgilanadi. new Function esa funksiyani ishlash vaqtida (runtime), istalgan satrdan yaratishga imkon beradi.

Bu shuni anglatadiki, funksiya kodini serverdan olib yoki dinamik ravishda shakllantirib, keyin uni bajariladigan funksiyaga aylantirish mumkin:

new-function-dinamik.js
// natija shu yerda chiqadi
Argumentlarni bitta satrda vergul bilan ajratib ham berish mumkin: new Function('a, b', 'return a + b') โ€” bu ham to'g'ri ishlaydi.

Closure va new Function

Bu yerda muhim va nozik jihat bor. Odatdagi funksiyalar o'zi yaratilgan joydagi tashqi o'zgaruvchanlarni "eslab qoladi" (closure). Ammo new Function orqali yaratilgan funksiya bunday emas โ€” uning [[Environment]] (leksik muhiti) global muhitga ishora qiladi, o'zi yaratilgan joyga emas.

Shuning uchun bunday funksiya tashqi lokal o'zgaruvchanlardan foydalana olmaydi โ€” faqat global va o'ziga uzatilgan argumentlarni ko'radi:

function getFunc() {
  let qiymat = "test"; // lokal o'zgaruvchan

  // Bu funksiya lokal 'qiymat'ni KO'RMAYDI:
  let func = new Function('return qiymat');

  return func;
}

// getFunc()(); // XATOLIK: qiymat is not defined
Agar oddiy funksiyada return function() { return qiymat; } yozganimizda, u lokal qiymatni ko'rgan bo'lardi. new Function esa faqat globalni ko'radi. Bu โ€” ataylab qilingan tarhli qaror.

Nega shunday? Chunki agar new Function lokal o'zgaruvchanlarni ko'ra olganida, minifikatsiya (kodni siqib, o'zgaruvchan nomlarini a, b kabi qisqartirish) paytida satr ichidagi nomlar mos kelmay, kod buzilar edi. Global muhit bilan cheklash bu xavfni yo'q qiladi.

Qachon ishlatiladi?

new Function juda kam hollarda kerak bo'ladi, lekin ba'zi vaziyatlarda bebaho:

Kundalik dasturlashda new Functionga deyarli murojaat qilinmaydi. U maxsus vosita โ€” faqat koddan dinamik funksiya yasash zarur bo'lganda tanlanadi.
Foydalanuvchidan olingan ishonchsiz satrni new Functionga (yoki evalga) uzatish โ€” xavfli. Bu zararli kod bajarilishiga olib kelishi mumkin. Faqat ishonchli manbadagi kod bilan ishlang.

Xulosa