Bildiiniz gibi JavaScriptte fonksiyonlar deerdir.
Her deerin bir tipi olduuna gre fonksiyonun tipi nedir?
JavaScriptte fonksiyon bir objedir.
Daha iyi grselleyebilmek adna fonksiyonlara aksiyon objeleri denebilir. Sadece ararak deil, obje olarak da davranabilirsiniz: zellik ekleme karma, referans paslama vs.
name zellii
Fonksiyon objelerinin kullanl zellikleri bulunmaktadr.
rnein, fonksiyonun ismi name zellii ile alnabilir.
function selamVer() {
alert("Selam");
}
alert(selamVer.name); // selamVer
name zellii atama o kadar aklldr ki, fonksiyon tanmlama ifadelerindeki ismi bile doru alr.
let selamVer = function() {
alert("Selam");
}
alert(selamVer.name); // selamVer
Hatta atama varsaylan deer ile yapldnda bile alr:
function f(selamVer = function() {}) {
alert(selamVer.name); // selamVer (alt!)
}
f();
Tanmda bu zellie balamsal isim denir. Eer fonksiyonda byle bir ey yoksa, tanmlama bunu ierikten alr.
Nesne metodlarnn da isimleri vardr:
let kullanici = {
selamVer() {
// ...
},
yolcuEt: function() {
// ...
}
}
alert(kullanici.selamVer.name); // selamVer
alert(kullanici.yolcuEt.name); // yolcuEt
Burada bir sihir yoktur. smin karlamad birok durum meydana gelebilir.
Byle durumlarda aadaki gibi bo dnerler:
// Dizinin ierisinde fonksiyon yaratlmas
let arr = [function() {}];
alert( arr[0].name ); // <bo>
// motorun doru ismi bulmasna imkan yok bundan dolay bo dnyor.
Pratikte ou fonksiyonun ismi bulunmaktadr.
length zellii
length adnda ayr bir zellik daha bulunmaktadr. Bu zellik fonksiyon parametrelerinin saysn dndrr:
function f1(a) {}
function f2(a, b) {}
function many(a, b, ...more) {}
alert(f1.length); // 1
alert(f2.length); // 2
alert(many.length); // 2
Grdnz gibi geriye kalan parametresi ... saylmamaktadr.
length zellii bazen dier fonksiyonlarn zerinde alan fonksiyonlara bir i bak oluturur.
Mesela, aadaki kodda sorfonksiyonu soru parametresi alr ve belirli olmayan sayda isleyici fonksiyonunu arr.
Kullanc cevap verdiinde isleyici(handler) arlr. ki trl ileyici gnderilebilir:
- Argmansz fonksiyon, sadece pozitif cevaplarda arlr.
- Argmanl fonksiyonlar, cevap alnan her durumda arlr.
Mantk u ekildedir; cevap pozitif olduunda argman almayan isleyici calisir, fakat evrensel isleyiciye de izin verir.
isleyicilerin doru almas iin, length zelliinden faydalanlabilir.
function sor(soru, ...isleyiciler) {
let dogruMu = confirm(soru);
for(let isleyici of isleyiciler) {
if (isleyici.length == 0) {
if (dogruMu) isleyici();
} else {
isleyici(dogruMu);
}
}
}
// Olumlu cevap iin, her ikisi alrken
// Olumsuz cevap iin sadece ikincisi almaktadr.
sor("Soru?", () => alert('Evet dedin'), sonuc => alert(sonuc));
Bu duruma polymorphism denilmektedir. Bu argmanlara tiplerine gre farkl davranma olaydr. Bu bizim durumumuzda lengthe baldr. Bu fikir JavaScript ktphanelerinde de kullanlmaktadr.
zelletirilmi zellikler
Kendi zelliinizi eklemek de mmkndr.
rnein aada counter zellii ile toplan ar says tutulmaktadr:
function selamVer() {
alert("Selam");
// Ka defa arldn tutar.
selamVer.counter++;
}
selamVer.counter = 0; // ilk deer
selamVer(); // Selam
selamVer(); // Selam
alert( `selamVer ${selamVer.counter} defa arlmtr` ); // selamVer 2 defa arlmtr.
Fonksiyona atanan selamVer.counter = 0 selamVer fonksiyonunun ierisinde counter deikenini tanmlamaz. Dier bir deyile counter zellii ile let counter birbirinden tamamen farkl eylerdir.
Fonksiyona obje gibi davranp zellik eklenebilir. Bu almasnda bir etki yaratmaz. Deikenler fonksiyon zelliklerini kullanmaz, keza fonksiyon zellikleri de deikenleri kullanmaz.
Fonksiyon zellikleri closure kullanlarak tekrardan yazlabilir. rnein yukardaki saya rneini Closure kullanarak tekrardan yazacak olursak:
function makeCounter() {
// let count = 0 yazmak yerine
function counter() {
return counter.count++;
};
counter.count = 0;
return counter;
}
let counter = makeCounter();
alert( counter() ); // 0
alert( counter() ); // 1
count artk fonksiyonun ierisinde bulunur, d ortamda deil.
Closure kullanmak iyi mi kt m?
Eer sayacn deeri dardaki deikende bulunuyorsa, dta bulunan kod buna eriemez. Sadece iteki fonksiyon bunu modifiye edebilir. Bu da anca fonksiyona balysa gerekleebilir:
function makeCounter() {
function counter() {
return counter.count++;
};
counter.count = 0;
return counter;
}
let counter = makeCounter();
counter.count = 10;
alert( counter() ); // 10
Bundan dolay asl nemli olan sizin hangi ekilde kullanmak istediiniz.
simlendirilmi Fonksiyon fadeleri ( Named Function Expression NFE )
simlendirilmi fonksiyon ifadeleri , NFE, daha nce kullandmz Fonksiyon fadelerinin isimlendirilmi halidir.
rnein, sradan bir Fonksiyon fadesi incelenecek olursa:
let selamVer = function(kim) {
alert(`Selam, ${kim}`);
};
isimlendirilirse:
let selamVer = function func(kim) {
alert(`Merhaba, ${kim}`);
};
Peki buradaki mantk ne? Ayrca bir "func" eklemenin ne anlam var?
Tekrar etmek gerekirse, hala bir Fonksiyon fadeniz var. Fonksiyon ifadesine "function" 'dan sonra "func" eklemek bu fonksiyonu Fonksiyon Tanm haline getirmez nk hala bir atama operasyonu ile tanmlanmtr.
Byle bir isim eklemek hibir soruna neden olmaz.
Fonksiyon hala selamVer() eklinde kullanlabilir:
let selamVer = function func(kim) {
alert(`Selam, ${kim}`);
};
selamVer("Ahmet"); // Selam, Ahmet
func ismine ait iki tane zellik vardr:
- Bu ekilde fonksiyonun kendisine ierisinden referans vermek mmkndr.
- Fonksiyonun dndan eriilemez.
rnein, selamVer fonksiyonu eer bir parametre olmadan arlrsa kendisini "Misafir" ile tekrardan arabilir.
let selamVer = function func(kim) {
if (kim) {
alert(`Selam, ${kim}`);
} else {
func("Misafir"); // kendisni yeniden arabilir.
}
};
selamVer(); // Selam, Misafir
// Fakat aadaki almayacaktr:
func(); // func tanml deildir. ( Fonksiyonun dndan eriilemez.)
Peki neden func kullanyoruz? Sadece selamVer kullansak olmaz m?
Aslnda ou durumda olur:
let selamVer = function(kim) {
if (kim) {
alert(`Selam, ${kim}`);
} else {
selamVer("Misafir");
}
};
Buradaki problem selamVerin deeri deiebilir. Fonksiyon dier bir deikene gidebilir ardndan hatalar vermeye balar.
let selamVer = function(kim) {
if (kim) {
alert(`Selam, ${kim}`);
} else {
selamVer("Misafir");
}
};
let hosGeldin = selamVer;
selamVer = null;
hosGeldin(); //Artk selamVer arlamaz.
Bunun olmasnn nedeni fonksiyonun selamVeri d ortamdan alyor olmasdr. Yerel bir selamVer bulunmadndan dtaki deiken kullanlmaktadr. O anda da dta bulunan selamVer nulldur.
Opsiyonel olarak konulan isim tam olarak Fonksiyon fadesinin bu problemini zer.
Bunu kullanarak kod u ekilde dzeltilebilir:
let selamVer = function func(kim) {
if (kim) {
alert(`Selam, ${kim}`);
} else {
func("Misafir"); // imdi hepsi doru ekilde alr.
}
};
let hosGeldin = selamVer;
selamVer = null;
hosGeldin(); // Selam, Misafir (i ar alr)
imdi alr, bunun nedeni "func"'in lokal fonksiyon olmasndandr. Dardan alnmaz ( dardan grnmez de ). Bu ekilde yazldnda var olan fonksiyonu referans verecei garantidir.
Dta bulunan kod hala selamVer veya hosGeldin deikenlerine sahiptir. Dtaki deikenlere bir ey olsa bile func"i fonksiyon ismi"'dir. Kendisini gizli biimde arabilir.
isel isim olarak tanmlanan zellik sadece Fonksiyon fadeleri iin geerlidir. Fonksiyon Tanmlarnda almaz. Fonksiyon tanmlar iin isel bir isim ekleme yntemi yoktur.
Bazen gvenli bir isme ihtiya duyulduunda Fonksiyon Tanm tekrardan simlendirilmi Fonksiyon fadesi ekline getirilir.
zet
Fonksiyonlar objedir.
zellikleri u ekildedir:
nameFonksiyon ismi. Sadece fonksiyon tanmlama da deil, atamalar ve obje zellikleri iin.lengthFonksiyon tanmndaki argman says, geriye kalan parametreleri ( ) saylmaz.
Eer fonksiyon Fonksiyon Tanm yntemi ile ( ana akta olmayan ) tanmlanmsa ve isim tayorsa buna simlendirilmi Fonksiyon Tanm denir. sim iersiinde veya recursive arlarda kullanlabilir.
Fonksiyonlar ayrca baka zelliklerde tayabilirler. ou bilinen JavaScript ktphanesi bu zellii ziyadesiyle kullanr.
Genelde bir ana fonksiyon ve bu fonksiyona bal birok yardmc fonksiyon tanmlarlar. rnein jquery $ adnda bir fonksiyon oluturur. lodash fonksiyonu _ adnda bir fonksiyon oluturu. Ardncan _.clone, _.keyBy gibi zellikleri ekler. Dkmantasyonu inceleyebilirsiniz. Aslnda, global alanda baya temiz alrlar. Bylece bir ktphane bir tane global deiken vermi olur. Bu da isimlerin birbiriyle akmasn engeller.
Bundan dolay bir fonksiyon kendince bir i yapabilir ve zellikleri vastasyla baka fonksiyonalitelere de sahip olabilir.
Yorumlar
<code>kullannz, birka satr eklemek iin ise<pre>kullann. Eer 10 satrdan fazla kod ekleyecekseniz plnkr kullanabilirsiniz)