Ushbu ochiq manbali loyihani butun dunyo bo'ylab odamlar uchun taqdim etmoqchimiz.

Ushbu qo'llanmaning mazmuni sizning tilingizga tarjima qilishga yordam bering!

Funktsiyani yaratishning yana bir usuli mavjud. U kamdan kam qo’llaniladi, ammo ba’zida boshqa alternativa yo’q.

Sintaksis

Funktsiyani yaratish uchun sintaksis:

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

Boshqacha qilib aytganda, funktsiya parametrlari (yoki aniqrog’i, ularning nomlari) birinchi bo’lib, tanasi esa oxirgi bo’ladi. Barcha argumentlar matnlardir.

Misolga qarab tushunish osonroq. Ikkita argumentli funktsiya:

let sum = new Function('a', 'b', 'return a + b'); alert( sum(1, 2) ); // 3

Agar argumentlar bo’lmasa, funktsiya tanasida faqat bitta argument mavjud:

let sayHi = new Function('alert("Salom")'); sayHi(); // Salom

Biz ko’rgan boshqa usullardan asosiy farqi shundaki, funktsiya to’liq ma’noda matndan yaratilgan bo’lib, u ishga tushirish vaqtida uzatiladi.

Oldingi barcha deklaratsiyalar bizdan, dasturchilardan, funktsiya kodini skriptga yozishni talab qildi.

Ammo new Function har qanday matnni funktsiyaga aylantirishga imkon beradi. Masalan, biz serverdan yangi funktsiyani qabul qilib, keyin uni bajarishimiz mumkin:

let str = ... kodni serverdan dinamik ravishda qabul qilish ... let func = new Function(str); func();

U juda aniq holatlarda, masalan, serverdan kod olganda yoki shablondan funktsiyani dinamik ravishda kompilyatsiya qilishda ishlatiladi. Bunga ehtiyoj odatda dasturlashning rivojlangan bosqichlarida paydo bo’ladi.

Yopish

Odatda funktsiya [[Environment]] maxsus xususiyatida qayerda tug’ilganligini eslaydi. U yaratilgan joydan leksik muhitga murojaat qiladi.

Ammo funktsiya new Function yordamida yaratilganda, uning [[Environment]] hozirgi leksik muhitga emas, aksincha global muhitga murojaat qiladi.

So, such function doesn’t have access to outer variables, only to the global ones.

function getFunc() { let value = "test"; let func = new Function('alert(value)'); return func; } getFunc()(); // error: value is not defined

Uni odatdagi xatti-harakatlar bilan taqqoslang:

function getFunc() { let value = "test"; let func = function() { alert(value); }; return func; } getFunc()(); // "test", getFunc leksik muhitidan

new Function ning bu o’ziga xos xususiyati g’alati ko’rinadi, ammo amalda juda foydali.

Tasavvur qiling, biz matndan funktsiyani yaratishimiz kerak. Ushbu funktsiya kodi skriptni yozish paytida ma’lum emas (shuning uchun biz oddiy funktsiyalardan foydalanmaymiz), lekin bajarish jarayonida ma’lum bo’ladi. Biz uni serverdan yoki boshqa manbadan olishimiz mumkin.

Bizning yangi funktsiyamiz asosiy skript bilan o’zaro aloqada bo’lishi kerak.

Ehtimol, biz uni tashqi mahalliy o’zgaruvchanlarga kirishini xohlaymiz?

Muammo shundaki, JavaScript-ni ishlab chiqarishga nashr etishdan oldin, u minifier – maxsus dastur yordamida siqiladi, bu qo’shimcha sharhlarni, bo’sh joylarni olib tashlash orqali kodni qisqartiradi va – eng muhimi, mahalliy o’zgaruvchanlarning nomlarini qisqaroqlariga o’zgartiradi.

Masalan, agar funktsiya userName ga ega bo’lsa, minifier uni let a (yoki boshqa bir harf bo’lsa) o’rnini egallaydi va hamma joyda bajaradi. Odatda bu xavfsiz narsa, chunki o’zgaruvchan mahalliy, funktsiyadan tashqarida unga kirish mumkin emas. Va funktsiya ichida minifier har bir eslatmani almashtiradi. Minifikatorlar aqlli, ular kodlar tuzilishini tahlil qiladi, shuning uchun ular hech narsani buzmaydi. Ular shunchaki topib-almashtiradigan soqov emas.

Ammo, agar new Function tashqi o’zgaruvchanlarga kira oladigan bo’lsa, u holda userName ni topib bo’lmaydi, chunki bu kod minifikatsiya qilinganidan keyin matn sifatida uzatiladi.

Hatto tashqi leksik muhitga new Function da kira olsak ham minifikatorlar bilan muammolarga duch kelamiz.

new Function ning “o’ziga xos xususiyati” bizni xatolardan xalos qiladi.

Va u kodni yanada yaxshi amalga oshiradi. Agar biz new Function tomonidan yaratilgan funktsiyaga biron bir narsani uzatishimiz kerak bo’lsa, uni aniq argument sifatida yetkazishimiz kerak.

Bizning “sum” funktsiyamiz buni to’g’ri bajaradi:

let sum = new Function('a', 'b', 'return a + b'); let a = 1, b = 2; // tashqi qiymatlar argument sifatida beriladi alert( sum(a, b) ); // 3

Xulosa

Sintaksis:

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

Tarixiy sabablarga ko’ra argumentlarni vergul bilan ajratilgan ro’yxat sifatida ham berish mumkin.

Ushbu uch narsa bir xil ma’noni anglatadi:

new Function('a', 'b', 'return a + b'); // asosiy sintaksis new Function('a,b', 'return a + b'); // vergul bilan ajratilgan new Function('a , b', 'return a + b'); // bo'shliqlar va vergul bilan ajratilgan

new Function bilan yaratilgan funktsiyalar tashqi leksik muhitga emas, balki global leksik muhitga ishora qiluvchi [[Environment]] ga ega. Demak, ular tashqi o’zgaruvchanlardan foydalana olmaydilar. Ammo bu aslida yaxshi, chunki bu bizni xatolardan xalos qiladi. Parametrlarni aniq o’tkazish arxitektura jihatdan ancha yaxshi usuldir va minifikatorlar bilan hech qanday muammo tug’dirmaydi.

O'quv qo'llanma xaritasi

Izohlar

izoh berishdan oldin buni o'qing…
  • Agar sizda nimani yaxshilash kerakligi haqida takliflaringiz bo'lsa - iltimos, GitHub muammosini yuboring yoki izoh berish o'rniga so'rov yuboring.
  • Agar siz maqolada biror narsani tushunolmasangiz - iltimos, batafsilroq ma'lumot bering.
  • Bir nechta so'z so'zlarini kiritish uchun <code> yorlig'ini ishlating, bir nechta satrlar uchun - ularni <pre> yorlig'i bilan o'rab qo'ying, 10 satrdan ortiq bo'lsa - sandbox (plnkr, jsbin, codepen…)