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.
Izohlar
<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â¦)