Ãok az kullanılsa da bir çeÅit daha fonksiyon yaratma Åekli vardır. Ãok az kullanılsa da bazen alternatifsizdirler.
Yazım
Fonksiyon yaratmak için:
let func = new Function('a', 'b', 'return a + b');
new Functionâın tüm argümanları karakter dizisidir. Parametreler önce, çalıÅacak kodun içeriÄi en son olarak yazılır.
ÃrneÄin:
let sum = new Function('arg1', 'arg2', 'return arg1 + arg2');
alert( sum(1, 2) ); // 3
EÄer argüman yok ise, sadece gövde ile fonksiyon yaratılır:
let selamVer = new Function('alert("Selam")');
selamVer(); // Selam
DiÄer yöntemlere göre en büyük farklılık â fonksiyon gerçektende sadece karakter dizisinden oluÅuyor, bu çalıÅma anında gerçekleÅiyor.
DiÄer tüm tanımlamalar programcıların kod yazmasını gerektirir.
Fakat new Function herhangi bir metini fonksiyona çevirebilir. ÃrneÄin sunucudan metin olarak bir fonksiyon alıp bunu çalıÅtırmak mümkündür.
let str = ... Serverdan dinamik olarak gelen metin...
let func = new Function(str);
func();
Tabi bunlar çok özel haller, örneÄin sunucudan bir metini alıp çalıÅtırmak, veya temadan dinamik olarak derleme. Bunun gibi ihtiyaçlar genelde geliÅtirmenin ileriki safhalarında karÅılaÅılır.
Closure
Fonksiyon genelde doÄduÄu yeri hatırlar [[Ortam]]. BulunduÄu Sözcüksel Ortama yaratıldıÄı yerden referans verir.
Bir fonksiyon new Function ile yaratıldıÄında [[Ortam]] referansı o anki bulunduÄu ortamı deÄil de evrensel ortama referans verir.
function FonkAl() {
let deger = "test";
let func = new Function('alert(deger)');
return func;
}
FonkAl()(); // hata: deger tanımlı deÄildir.
Normal davranıŠÅu Åekildedir:
function FonkAl() {
let deger = "test";
let func = function() { alert(deger); };
return func;
}
FonkAl()(); // "test", FonkAl'ın sözcüksel ortamından.
new Function özelliÄi biraz garip dursa da çok kullanıÅlı ve pratiktir.
DüÅününkü gerçekten de karakter dizisinden fonksiyon yaratmanız gerekti. O fonksiyonun ne olduÄu hangi kodları kapsadıÄı baÅtan belli olmayacaktı ( bundan dolayı normal fonksiyonlar kullanılamaz ), fakat çalıÅma anında fonksiyon yaratılacak. Bu fonksiyon sunucudan veya diÄer bir kaynaktan alınabilir.
Yeni fonksiyon ana kod akıÅı ile etkileÅime geçme ihtiyacında olabilir.
Belki dıÅta bulunan yerel deÄiÅkene eriÅmek gerekmektedir.
Fakat burada Åöyle bir problem var. JavaScript canlı ortama çıkmadan sıkıÅtırıcı (minifier) kullanılır ve böylece gereksiz boÅluklar vs kaldırılır. Fakat daha da önemlisi, yerel deÄiÅkenler kısaltılarak iÅlenir.
ÃrneÄin bir fonksiyon let kullaniciAdi diye bir fonksiyona sahip olsa, sıkıÅtırıcı bunu let k Åeklinde veya bu deÄiÅken daha önce kullanılmıÅsa baÅka küçük bir deÄiÅken ile tutar. Bu aslında mantıklı olandır. DeÄiÅken zaten yerel bir deÄiÅkendir ve dıÅarıdan buna eriÅilemez. Bundan dolayı fonksiyonun içerisinde kullanılan her kullaniciAdi yeni deÄiÅken ismiyle deÄiÅtirilir. SıkıÅtırıcılar kodu ve kod yapısını analiz ederler sadece bul ve deÄiÅtir iÅlemi yapmazlar.
Fakat new Function dıÅtaki deÄiÅkenlere eriÅebilir olsa isi bu defa kullaniciAdiânı bulamazdı.
DıŠfonksiyonlara eriÅilme mümkün olsa bile new Function sıkıÅtırıcılar ile problem yaÅardı
new Functionâın bir özelliÄi bizi hata yapmaktan kurtarır ve daha iyi kod yazmamıza yardımcı olur.
EÄer new Function ile yazılmıŠbir fonksiyona argüman göndermek istiyorsanız, bunu argümanları birer birer belirterek yapmanız gerekmektedir.
âtoplaâ fonksiyonu aslında bunu doÄru bir Åekilde yapmaktadır:
let topla = new Function('a', 'b', ' return a + b; ');
let a = 1, b = 2;
// DıŠdeÄerler argüman olarak gönderilmiÅtir.
alert( topla(a, b) ); // 3
Ãzet
Yazım:
let func = new Function(arg1, arg2, ..., govde);
Eski kodlara uyumluluktan dolayı argümanlar virgül ile ayrılmıŠliste olarak da verilebilir.
AÅaÄıdaki üç örnekte birbiri ile aynıdır:
new Function('a', 'b', ' return a + b; '); // basit yazım
new Function('a,b', ' return a + b; '); // virgül ile ayrılmıŠyazım
new Function('a , b', ' return a + b; '); //virgül ve boÅluk ile ayrılmıŠyazım.
new Function kullanılarak yaratılan fonksiyonlar, [[Ortam]] olarak Evrensel Sözcük Ortamını referans verir, dıŠdeÄil. Bundan dolayı dıÅtaki deÄiÅkeni kullanamazlar. Fakat bu aslında iyi bir Åeydir, bizi hatalardan korur. Bire bir parametre gönderme de mimari olarak çok baÅarılır. Ayrıca sıkıÅtırıcı ile de probleme neden olmamaktadır.
Yorumlar
<code>kullanınız, birkaç satır eklemek için ise<pre>kullanın. EÄer 10 satırdan fazla kod ekleyecekseniz plnkr kullanabilirsiniz)