You are on page 1of 15

leri Seviye Javascript

Yazan: Azer Koulu

ndeks
Giri Fonksiyonlar 1. Parantez Bloklar 1. Argmanlar 1. Fonksiyonlar in Method ve Alt Deiken Tanmlamak 1. Apply 1. Call 1. Prototype 1. Caller 1. Blm Sonu Pratikleri Diziler Nesneler leri Seviye OOP

Giri
Bu dkmanda Javascript'in deneysellie dayanan doasna uygun biimde, web tabanl program retmenizi salayacak bilgileri vermeye altm. zellikle stnde durmanz gereken konu olan fonksiyonlarda, kitaplarda yeralmayan ileri teknik ve pratikleri anlattm. Dkmandan iyi verim almak iin, Rainbow9'dan faydalanabilirsiniz. Rainbow9, geen yl hazrladm, javascript deneyleri yapmay ve web tabanl programlar gelitirmeyi salayan bir programdr.sterseniz Firefox'un Firebug eklentisinden de faydalanabilirsiniz.Rainbow9, Firebug'n aksine baz mobil tarayclar dahil tm tarayclarda kurulmaya gerek olmadan alr. Rainbow9: http://www.rainbow9.org Firebug: http://www.getfirebug.com Dkman okuyup bitirdikten sonra daha deneysel ve iyi tekniklerle kod yazacanz, kod standartnz gelitireceinizi umut ediyorum. Sabr ve gayretlerinizin karln almanz dileiyle, Azer Koulu <http://azer.kodfabrik.com> Destekleyen, yardm eden, moral verenlere teekkr ederim: Annem Nuray Koulu, Can atalyrek, Hakan Bilgin, Muhammed Daud

Fonksiyonlar
C tabanl dillerde her i veya alt i fonksiyonlar tarafndan yrtlr.Fonksiyonlarn genel kullanm ekli, argman tnelinden veri gnderip, bilgi k beklemektir.Genel yazl inceleyelim:

function(argmanlar){ return argman }


Gnderilen argmanlar herhangi bir trde olabilir, say, dizi fonksiyon...Buradaki tek dikkat unsuru argmanlarn her birine ayr tantc belirlenmesidir.Argmanlar birden fazlaysa birbirlerinden virglle ayrlmalar gerekir:

(argman1,argman2,argman3...)
ECMAScript'in kullandmz srmnde, argmanlar iin PHP veya Python dillerinde olduu gibi varsaylan deer atanamaz.Deer atanmayan argmanlarn tantclar yine tanmlanr ancak "undefined" trnde olurlar.Argmanlar sadece tanmlandklar fonksiyonda altrlabilirler.Global blokta tanmlanan deikenlere fonksiyonlardan eriilebilir. Bir fonksiyonda en son, fonksiyondan geriye deer dndrlmesini salayan "return" ifadesi altrlr.Eer bu ifadeden sonra fonksiyonun ierii bitmediyse, ECMAScript bu ierii grmezden gelir. Fonksiyonlar eitli biimlerde tanmlanabilir, ilk olarak tantc ve eit iareti kullanarak klasik biimde tanmlayalm:

var islem = function(){}


Biraz daha pratik olan dier yntemdeyse pek ok programlama dilinden alk olduumuz biimde tanmlyoruz:

function islem(){}
rnek olarak argman tnelinden ald iki saynn toplam geriye dndren bir fonksiyon tanmlayalm:

function topla(sayi1,sayi2){ return sayi1+sayi2 }


Bu biimlerde tanmlamalar genelde tercih edilse de, bazen programn akna gre ekillenmesi gereken fonksiyon tanmlamaya ihtiya duyulur.Bu durumda tantclarn program altrlmadan nce belirlenmek zorunda olmas, pek ok dilde rastladmz bir kstlamadr.Fakat

ECMAScript'in Function() nesnesi sayesinde, kod blou tantc string tipinde belirtilerek, programn akna gre ekillenen fonksiyonlar tanmlanabilmektedir:

var topla = new Function("sayi1","sayi2","return sayi1+sayi2")


Fonksiyonlarn atama ilemleri dier veri trleriyle ayn olsa da, fonksiyona ulap altrma ilemi ayr biimdedir.Bir fonksiyonu altrmak iin tantcyla beraber argman tneli kullanlr.Burada argman tnelinin veri transferi yapp yapmamas farketmez.rnek olarak hazrladmz topla fonksiyonunu kullanalm:

>>> var sonuc = topla(5,4) 9


"sonuc" deikeni integer trnde 9 deerini ald. rnekteki topla() fonksiyonunda hem bilgi girii hem de bilgi k yaplyor, imdi bilgi girii veya k yaplmayan bir rnei inceleyelim:

>>> var durum = 'Negatif'; >>> var durumuAyarla = function(){ durum = 'pozitif' }
Bu rnekteyse programn global blounda "durum" adnda bir deiken ve "durumuAyarla" adnda, "durum" deikeninin deerini string tipinde "pozitif" deeriyle deitiren bir fonksiyon oluturuluyor.altrp deneyelim;

>>> durumuAyarla() undefined >>> durum 'pozitif'

Parantez Bloklar
Fonksiyon tipindeki verilerin almasn incelediimiz rneklerde parantezlerin saladn gryoruz.Parantezler ilevsel olarak pek ok konuda fayda salasa da, pek ok zaman yazlan kodun daha anlalr olmas iin blok oluturmada kullanlr.nce ne gibi ilevlerde kullandmza gzatalm.Birinci rnek matematiksel ilemlerde gruplama yaparken kullanlan parantezler zerine:

>>> 1+2*3 7 >>> (1+2)*3 9


kinci rnek, saysal deerlerin ondalk ksmyla methodlarn karmas problemine parantez zm:

>>> 1.toString() missing ; before statement [Break on this error] 1.toString() javascript: with ... (line 1) >>> 1.0.toString() "1" >>> (1).toString() "1"
Gelelim nc rnee.Ecmascript'te her fonksiyon blou parantezler iine alnabilir.Ve elbette, parantez iine alnm kod blouna altrma komutu gnderilebilir.Bu yntem daha sade ve temiz grnen kodlar yazmay salar, nk fonksiyonu yazdktan sonra tantcy armaya gerek duyulmaz. Klasik yntemle yazlan bir fonksiyonun arma ilemiyle, parantez blounun kodlarn karlatralm:

>>> var merhaba = function(){ return "Merhaba" } >>> merhaba(); Merhaba >>> (var merhaba = function(){ alert("Merhaba"); })(); "Merhaba"
lk rnekte fonksiyonu tanmladk ve ardndan tantcsn kullanarak altrdk, ikinci rnekteyse fonksiyonu parantez bloklarnn iine alp altrdmz iin, tantcyla arma yaptmz satra gerek kalmad.Tahmin edeceiniz zere, aslnda parantez bloklarn kullanrken tantc kullanlmayabilir:

>>> (function(){ alert("Merhaba"); })(); "Merhaba"

Argmanlar
Fonksiyonlar, sadece faaliyet alanlarnda eriilebilir durumda olan deerler alabilirler.Bu deerlerin tantcs, fonksiyon oluturulurken argman tnelinde yazlr.Fakat gnderilen argmanlar iin tantc belirtmek zorunlu deildir, tantc olsun veya olmasn, fonksiyon iindeki "arguments" tantcl deiken argman tnelindeki tm verileri saklar. Diziler, tek tantcnn altnda veri paralarn tantcya ihtiya kullanmadan saklamay salayan veri trdr, rnek olarak herbiri tek bana bir deer olan birka elmay tutan sepeti dnelim.Sepeti tutan el, programmz altran browser olmal :) Fonksiyonlardan bir sonraki konu balnda dizileri daha detayl inceleyeceiz. Az nce szn ettiim "arguments" deeri, fonksiyonlarn argman tnelinden gelen tm deerleri sral olarak saklayan bir dizidir.Tantcs olsun veya olmasn, browserlar gnderilen tm argmanlara erimemizi salar.Bir rnek;

>>> var argumanlar = function(){ return arguments; } >>> argumanlar(3,5); 3,5 >>>
rnekte "argumanlar" adnda, tek ilevi kendisine gelen argmanlar geri dndrmek olan bir fonksiyon oluturduk ve bu fonksiyona gnderdiimiz argmanlarn bize dizi tipinde geri dndn grdk.Toplama rneini "arguments" dizisinin elemanlarn seip ilem yaptrarak yeniden ele alalm:

>>> var toplama = function(){ return arguments[0]+arguments[1]; } >>> toplama(3,5); 8


Bu rnekte arguments dizisinin ilk iki elemann, tantclar olan sra numaralaryla setik ve toplamlarn bulup geri dndrdk.Dizileri henz iyice anlamadnz dnyorsanz endielenmeyin, dizileri ayr bir balkta detayl biimde inceleyeceiz. Fonksiyonlarn iinde ka argman tanmlandn bulmak iinse, fonksiyon tantcsnn alt deikeni olan .length deeri kullanlr.rnek olarak, argman tnelinde tanmlanan deikenlerin saysn gnderen bir fonksiyon yazalm:

>>> function test(arguman1,arguman2){ return test.length; } >>> test() 2

Fonksiyonlar iin method ve alt deiken tanmlamak


ECMAScript'te, fonksiyonlarn her biri dier dillerde rastladmz "class"'lara benzer, alt deerler tanmlanabilir ve new operatryle klonlanabilir. Alt deer tanmlamak iin, fonksiyonun iindeki "this" deerine eriilir.Alt deerler fonksiyon blounun dnda da tanmlanabilir. Bir rnek;

>>> var islemci = function(){ this.aciklama = "merhaba dnya!" this.toplama = function() { return arguments[0]+arguments[1]; } this.cikarma = function(sonuc) { return arguments[0]-arguments[1]; } } >>> var islem1 = new islemci(); >>> islem1.toplama(3,5); 8 >>> islem2.cikarma(3,5); -2
islemci adnda, toplama cikarma methodlarn ieren bir fonksiyon yarattk ve ardndaki satrda, islem1 tantcsna yeni bir islemci objesini atadk.Bu kez, az nce yazdmz islemci objesinde, prototype kullanarak yeni bir alt method yaratalm;

>>> islemci.prototype.carpma = function(){ return arguments[0]*arguments[1]; } >>> var islem2 = new islemci(); >>> islem2.carpma(3,5); 15
prototype

Klonlanabilir nesnelerin ortak etki alanna sahip olmasn salayan bir deerdir.Eer prototype kullanmadan tanmlama yaparsak, alt methodu olduumuz objenin etki alanna yani ierdii deerlere eriemeyiz.Buna bir rnek verelim:

>>> islemci.prototype.aciklamayiGoster1 = function(){ return this.aciklama; } >>> islemci.aciklamayiGoster2 = function(){ return this.aciklama; }
Grevleri islemci objesine ait aciklama deerini dndrmek olan etki alanlar farkl, iki tane fonksiyon tanmladk.lk tanmladmz fonksiyonu deneyelim:

>>> islemci.aciklamayiGoster1() "merhaba dnya!"


Grdnz gibi, islemci nesnesine prototype kprsnden eriti ve ierdii deerleri ald.Dierini deneyelim:

>>> islemci.aciklamayiGoster2() undefined


Tanmlanmam deer dndrd nk etki alan kendisiydi.sadece kendi iindeki ve window altndaki deerlere ulaabilirdi.Elbette bu problem zmsz deil, call ve apply methodlar fonksiyonlarn etki alann belirlememizi salar. Dardan Eriime Kapal zellikler C Tabanl programlama dillerindeki class yaplarnda, methodlarn darndan eriime ak olup olmad belirtilebilir.ECMAScript'in yeni srmndeki class yaplar da public/private alt method ve deerleri destekler. u an kullandmz srmde de public/private zellikler oluturulabiliyor, bunun iin fonksiyon bloklarnn etki alanlarndan faydalanlr;

>>> function test(){ var _deger = "merhaba dnya!"; this.degeriGetir = function(){ return _deger; } }
Yukaridaki rnekte test adnda bir fonksiyon oluturduk ve biri dardan eriime kapal, iki deer oluturduk.

>>> test1 = new test(); >>> test1._deger undefined >>> test1.degeriGetir() "merhaba dnya!"

Apply
apply Javascript'in isvire aksdr.Bu zellik sayesinde, fonksiyonlar birbirlerinin yaplarnn stne ina edilebilir ve bunun saymakla bitmez faydalarndan biri, modern object oriented dillerinin kaltm zelliini bize salamasdr.rnein, kimlik bilgileri ieren "kii" objesi zerine, skor ve benzeri bilgileri ieren "oyuncu" objesi oluturalm:

>>> var kisi = function(adsoyad,yas,dogumyeri){ this.adsoyad = adsoyad; this.yas = yas; this.dogumyeri = dogumyeri; } >>> var arda = new kisi("Arda Koulu",17,"Kars"); >>> arda.dogumyeri "Kars"
Kii objesini inceleyelim; bir fonksiyon oluturduk ve argman tnelinden gelen veriyi bu fonksiyona alt deer olarak atadk.Ardndaki satrda "arda" deerini "new" operatryle yeni bir kii olarak tanmladk.Kii objesini oluturduumuza gre, oyuncu objesine de geebiliriz:

>>> var oyuncu = function(adsoyad,yas,dogumyeri,takim,skor){ this.takim = takim; this.skor = skor; kisi.apply(this,arguments); } >>> var kemal = new oyuncu("kemal akn",15,"antalya","maviler",3); >>> var ege = new oyuncu("ege akn",10,"izmir","krmzlar",2); >>> kemal.takim maviler >>> ege.dogumyeri izmir
Oyuncu adnda bir nesne oluturduk, argman tnelinden beklediimiz deerleri tantclarna tanmladktan sonra, takim ve skor alt deerlerini atadk.Ardndan gelen satrda ise, kisi objesinin apply methodunu altrdk ve "this","arguments" argmanlarn gnderdik. "this" argman, kii objesinin hangi fonksiyon tarafndan arldn gndermek iin kullanlr.arguments Argmanysa, apply methoduyla arlan fonksiyonun argman tnelinden bekledii argmanlar gndermemizi salar."arguments" deeri, oyuncu fonksiyonuna gelen deerleri ierdiinden, "oyuncu"

fonksiyonuna gelen tm argmanlar "kisi" fonksiyonuna gnderililir.

Call
call fonksiyonu tpk apply gibi, fonksiyonlar kendi belirlediimiz etki alan ve argmanlarla altrmamz salar.Bir problemin zmn anlatarak rnek yapalm, javascript arguments dizisinin alt methodlarn kullanmamza olanak tanmaz.Deneyelim;

>>> (function(){ alert(arguments.slice); // undefined deer dner })("merhaba","dnya");


Parantez bloklar iindeki fonksiyonumuza iki metinsel deer gnderdik.Fonksiyondaysa, gelen argman listesinin slice methodunu kontrol ediyoruz ve tanmlanmam olduunu gryoruz. imdi bu problemin zmn inceleyelim:

>>> (function(){ alert(Array.prototype.slice.call(arguments,1) // dnen deer: ["dnya"] })("merhaba","dnya");


slice Methodunun ilevi o kadar nemli deil, diziler konusunda inceliyoruz.Burada dikkat etmeniz gereken, prototipteki fonksiyon kaynana ulamamz ve bu fonksiyonu call methodu ile armamz.call nesnesine gnderdiimiz argmanlardan birincisi etki alann belirliyor, dieri ise slice methodunun argman tnelinden bekledii ilk deer. Grdnz gibi, call methodu applyden farkl olarak argmanlar topluca liste olarak almyor, ilk argman etki alan deeri kabul edip dier btn argmanlar altrd fonksiyona aktaryor.

Call ile kaltm Kaltm ilikileri kurmak iin apply'den daha ok tercih edilen methoddur.Mantk olarak pek farkllk yok, istenen objeye "scope" ve argmanlar gnderiliyor:

>>> var kisi = function(adsoyad,yas,dogumyeri){ this.adsoyad = adsoyad; this.yas = yas; this.dogumyeri = dogumyeri; } >>> var oyuncu = function(adsoyad,yas,dogumyeri,takim,skor){ this.takim = takim; this.skor = skor; kisi.call(this,adsoyad,yas,dogumyeri); } >>> var kemal = new oyuncu("kemal akn",15,"antalya","maviler",3); >>> var ege = new oyuncu("ege akn",10,"izmir","krmzlar",2); >>> kemal.takim maviler >>> ege.dogumyeri izmir
rnekte grdnz gibi, apply ile temel farkllk call methodunun argmanlar serbest biimde gndermemizi salamas.

Prototype
Prototype' bir binann iskeletine benzetebiliriz, hatta bu benzetmeye tahmin ediyorum birka yz dkmanda daha rastlayabilirsiniz nk prototype benzetmeden daha te, fonksiyonlarn iskeletidir. Prototype deerlerinin tipi objedir.Yani bir objeyi alp, bir fonksiyonun iskeleti olarak kullanmak mmkndr.Tabii bunun tam tersi durum da szkonusu. Fonksiyonlarn klonlanarak objeye dntrlmesini anlatrken bir detay atlamtk; objenin zellikleri fonksiyonun tanmland blokta olmak zorunda deil.Oluturduumuz fonksiyonun iskeletine ulaabilir ve eitli eklemeler yapabiliriz.imdi adm adm bir fonksiyon yazalm ve konsolun dndrd deerleri yorumlayalm:

>>> var kisi = function(adsoyad,yas,dogumyeri){ this.adsoyad = adsoyad; this.yas = yas; this.dogumyeri = dogumyeri; } >>> kisi.prototype Object: There are no properties to show for this object.
rnekte kisi adnda bir fonksiyon oluturup iine adsoyad,yas,dogumyeri zelliklerini yazdk.Ardndaki satrda prototype' incelediimizde, bo bir objenin dndn gryoruz.Bu durumdan unu karmalyz, iskeletin inas prototype objesi dnda yaplamaz.Veya yle zetleyelim, fonksiyonun iinde iskelet oluturamayz.

>>> kisi.prototype.meslek = null;


Yukaridaki rnekte prototype objesinin altnda bir alan aarak, kisi fonksiyonuna meslek adnda bir zellik ekledik.

>>> kisi.prototype

Object: (meslek = null) >>> selcuk = new kisi("seluk koulu",48,"mardin"); >>> selcuk.meslek null
Bu rnekteyse selcuk adnda bir obje oluturduk ve meslek zelliini sorguladk.Dnen sonucun null -bu bizim belirlediimiz bir varsaylan deerdi- olduunu gryoruz. Buradaki problem, iskelete sonradan eklenen meslek zelliini constructor'a nasl dahil edeceimiz.Bu i iin constructor'n yeniden yazlmas kanlmazdr;

>>> var kisi = function(adsoyad,yas,dogumyeri,meslek){ this.adsoyad = adsoyad; this.yas = yas; this.dogumyeri = dogumyeri; this.meslek = meslek; } >>> fikretkizilok = new kisi("fikret kzlok","60","stanbul","Mzisyen"); >>> fikretkizilok.meslek "mzisyen"
Bu rnekte dikkat etmemiz gereken, kisi fonksiyonunun eski iskeleti devralmas.Peki bu durumda henz tanmlanmam fonksiyonlarn iskeleti oluturulabilir mi? Evet, oluturulabilir. Bunu denemek iin yeni bir fonksiyon yazalm:

>>> >>> >>> >>>

kargo.prototype.alan = null; kargo.prototype.gonderen = null; kargo.prototype.kargoicerigi = null; function kargo(alan,gonderen,kargoicerigi){ this.alan = alan; this.gonderen = gonderen; this.kargoicerigi = kargoicerigi;

} >>> kargo.prototype.ucret 0
Grld gibi, undefined deeri olan bir tantc altnda iskelet oluturduk ve ardndan bu tantcya fonksiyon deeri verdik.Son satrda ise, tantc deer almadan oluturduumuz iskeletin alr durumda olduunu onayladk.Biraz nce yazdmz kisi nesnesinden de faydalanarak kargo'nun kullanmna bir rnek verelim:

>>> var azerkoculu = new kisi("azer koulu",20,"ka","web gelitirici"); >>> var billgates = new kisi("bill gates",53,"seattle","iadam"); >>> var yeniKargo = new kargo(azerkoculu,billgates,"mozilla stickers");
Prototype ve Browser Nesneleri Javascript'in disable olmad durumlar saymazsak, browserlar her HTML belgesinde javascript komutlarnn almasn salayan bir zemin oluturur.String,Number,Function,Array,Object nesneleri browser szettiimiz ekirdekte yer alan nesnelerden birkadr. Yazdmz her say Number objesinden, her yaz String objesinden trer.Ve tahmin edeceiniz gibi, bu deerlerin methodlar, ekirdekteki nesnelere baldr.String nesnesinin methodlarndan birini deneyelim:

>>> String String() >>> String.prototype.replace replace()


String nesnesinin prototype objesindeki replace fonksiyonuna eriip kontrol ettik.imdi de oluturacamz string deerinde replace methodunun kullanmn inceleyelim:

>>> "Merhaba Dnya".replace replace()


ECMAScript standartn kullanan dillerden biri de Actionscript'tir.Bu dil de String,Number gibi objeler oluturur fakat gelitiricinin bu nesneleri deitirmesi kstlanmtr. Neyse ki javascript iin byle bir durum sz konusu deil, browser nesnelerini dilediimiz gibi deitirebilmekteyiz.rnek olarak Number objesine bir method ekleyelim:

>>> Number.prototype.topla = function(sayiDegeri){ return this+SayiDegeri }


Number nesnesinin iskeletine "topla" adnda bir fonksiyon ekledik.Bylece, tm saylar iin pratik bir toplama methodu yaratm olduk, deneyelim:

>>> (4).topla(8) 12 >>> 4.0.topla(8)

12
Aklnza u soru gelmi olmal: Peki ondalk hanelerin nokta iaretleriyle methodlarnki karmaz m? Evet karr.Bunun iin saylar parantez iine alnr, veya ondalk hanesinden sonra method yazlr. rnekte grdnz gibi, Number snfndan treyen say deerlerinin altnda topla methodu kendiliinden gelmektedir. Kk bir ipucu: prototype Obje tipindedir yani Object snfndan tremitir.imdi browser'mz heyecanlandracak birka deneme yapalm:

>>> Object.prototype.deneme = "foo bar" >>> "".deneme "foo bar"


rnekte, Object snfnn iskeletine bir ekleme yaptk ve bylece Object sfndan tremi olan tm iskeletlere deiiklii uyguladk.Yani, deneme fonksiyonu tm iskeletlere eklendi.Bir sonraki satrda oluturduumuz string deeri kontrol ettik ve bu durumu doruladk. Protype'lar hakknda genel bilgi sahibi oldunuz.Obje trlerini inceledikten sonra prototype'lara tekrar dnp deney yapmanzda fayda var.

Caller
Fonksiyonlarn nasl arldn anlamak iin, alt zellikleri olan "caller" kontrol edilir, eer herhangi bir fonksiyon iinde arlmadysa, "null" deerini dndrr.Bu zellik "fonksiyonAd.caller" biiminde kullanlr:

>>> var merhaba = function(){ return merhaba.caller; } >>> merhaba() null >>> (function(){ return merhaba() })() (function(){ return merhaba() })()
rnekte, "merhaba" adnda, kendisini aran fonksiyonu dndren bir fonksiyon oluturduk.Global blokta ardmz satrda "null" deer dnerken, dierinde fonksiyonun kendisi dnd. rnek olarak, yazdmz fonksiyonun baka bir fonksiyon iinden arlmasn engelleyebiliriz;

>>> var merhaba = function(){ if(merhaba.caller!=null) return "Bu fonksiyona baka bir fonksiyonun iinden eriemezsiniz." return "Merhaba!"
Dizi konusu gibi, ileride detaylca inceleyeceimiz konulardan biri de koullar.Yukardaki rnein ilk iki satrnda, "merhaba.caller" deerini kontrol ettik ve eer "null" deilse, yani bir baka fonksiyonun iinden ar yapldysa, "Merhaba" yerine uyar metni dndrdk."return" komutu verildikten sonra yorumcunun fonksiyondan ktn hatrlayalm. Internet Explorer ve eval() stisnas "Caller" Internet Explorer, Mozilla gibi popler tarayclarn destekledii, aslnda standart d bir zelliktir.Fakat Internet Explorer "eval()" komut blounda altrlan fonksiyonlar iin de caller deerini "null" dndrmektedir.Kontroller yaplrken bu durumu dikkate almak gerekir.

Blm Sonu Pratikleri


SORULAR Soru 1) Dinamik fonksiyon yazmna rnek vermek iin, sayfa baln statik string olarak dndren "sayfaBasligi" adnda fonksiyon yaznz. Soru 2)Javascript yazarken ska karlalan sorunlardan biri, altrlan fonksiyonlarn istenen scope'a sahip olmamasdr.Bu tr problemlerin zmne rnek vermek iin, herhangi bir fonksiyonun scope deerini herhangi bir objeyle deitiriniz. Soru 3) nceki sorudan devam.Scope problemlerinin zmn daha pratik hale getirecek "curry" adnda bir fonksiyon methodu yaznz. CEVAPLAR Cevap 1) Fonksiyonlar Function snfndan trer.Klasik yazln yannda new operatryle Function snfndan fonksiyon oluturulabilir;

var fonksiyon = new Function(argman1,argman2,......,fonksiyonKodlar);


Buna gre sorunun cevab;

var sayfaBasligi = new Function("return '"+document.title+"'");


Cevap 2) Bu problem hakknda detayl bilgiyi call ve apply balklarnda bulabilirsiniz.Sorunun yant ise yle:

var deneme = function(){ alert(this.adres); } deneme(); // undefined deneme.call({ "adres":"google.com" }); // google.com
Deneme adnda bir fonksiyon oluturduk ve ikinci satrda altrdk.Fonksiyonumuz altnda, kendisine ait "adres" adnda bir methodu arad ve

byle bir method tanmlanmadndan undefined deer dnd.nc satrda ise deneme fonksiyonunun call methoduna bir obje gnderdik.Deneme fonksiyonu bu kez altnda kendisinin etki alann gnderdiimiz Bu problemin nasl alacan call ve apply balklarnda detaylaryla anlattm, imdiyse bu ii olduka pratik bir hale getirelim. rnein, herhangi bir fonksiyonu u biimde aralm ve istediimiz scope'u uygulayalm:

>>> var deneme = { kontrol: false } >>> deneme.kontrol false


kontrossl

adnda bir boolean ieren deneme objesi oluturduk, imdi bu objeye iki ayr yolla erielim:

>>>var deneme = { kontrol: true }; >>>var kontrolDegeri = function(){ return this.kontrol; }; kontrolDegeri(); // undefined dner kontrolDegeri.call(deneme); // "true" dner
Kontrol deerini ilk armzda bize deer dnmedi ancak ikinci arma biiminde istediimiz deer dnd.Burada call methoduna scope deeri olarak deneme objesini gnderdik ve bylece fonksiyonun iindeki this deeri, deneme objesine referansland.lk satrda ise fonksiyonun ierii scope olarak window objesine eritiinden, istediimiz deer dnmedi. Cevap 3) Bir veri trne method atamak iin, o veri trnn constructor' zerinde ilem yapmak gerekir.Daha ayrntl bilgi almak iin, prototype balna dnn. Soruda bizden isteneni daha ak hale getirelim; her fonksiyonun "curry" adnda bir methodu olacak ve biz bu methoda istediimiz scope'u gnderdiimizde, bize yeni bir fonksiyon deeri gnderecek.Elde ettiimiz yeni fonksiyonu dilediimiz gibi altrabileceiz, yani fonksiyonumuz apply veya call ilemlerindeki gibi, scope gnderilince hemen almayacak.nce rnek kullanm inceleyin:

>>> var kontrolDegeri = kontrolDegeri.curry(deneme); >>> kontrolDegeri(); // true deeri dnd


Bu kezcurry methodunu kullanarak, deneme objesini kontrolDegerinin scope'u olarak belirledik ve yeni bir fonksiyon deeri elde ettik.Eer kontrolDegeri ve deneme objesinin nerede oluturduumu kardysanz, ikinci sorunun zmne gzatn.
curry

Methodunun yazmnda ncelikle dikkat etmemiz gereken, bir fonksiyon deeri dndrecek olmamz, bir dier nemli unsursa, argmanlar da kullanacak olmamz.call ve apply balklarnda, argmanlarn nasl kullanldn anlatmtm, tekrar gzatabilirsiniz.Yazmaya balayalm:

>>> Function.prototype.curry = function(scope){ var fn = this; var scope = scope||window; return function(){ fn.apply(scope,arguments); } }
Grdnz gibi pek karmak bir zm olmad.lk satrda, fn adnda bir deer tanmladk bunun sebebi, geri dndrdmz fonksiyon deerinin iinden, st fonksiyona eriemeyiimiz.Ancak st fonksiyon blounda tanmladmz deerler, birbirine eriebilir.Bu yzden, scope deerini de tekrar tanmladk.Genellikle mantksal sorgulamalarda kullandmz "veya" ifadesinin grevi ise, argman olarak gelen scope deeri null,false veya undefined olduunda, window deerini dndrmektir.Daha sonraki satrda ise, bir fonksiyon deeri dndryoruz.Yeni fonksiyonun ieriine baktmzda bu kez call deil apply kullandmz grrsnz.Bunun sebebi, call methodunun argmanlar array tipinde deil, tek tek almas.apply ise bunun tam tersine, ilk argmandan sonra bir argmanlar ieren dizi deeri bekler.Gnderdiimiz arguments deeri, yeni fonksiyona gelen argmanlar ieren dizi deeridir.Bunun hakknda daha fazla bilgi istiyorsanz, argmanlar balna dnn.

Diziler: array
stenen veri paralarn tr ayrm yapmadan bir araya getirip gruplayan veri trdr.ECMAScript dizi elemanlarnn tantclarn sra numaras olarak tanmlar.Deer atama ilemi keli parantezler iinde dizi elemanlarn virglle ayrarak yaplr:

var tekSayi = [1,'Bir',3,'',5,'Be']


rnekte integer ve string trndeki verilerle bir dizi oluturduk.Fakat istenirse, bir dizi elemannn tipi herhangi bir veri tr olabilir, rnein number, veya yine array trnde bir dizi eleman oluturabiliriz.

boolean, function, object

Program iinde diziye erimek istendiinde, dizi elemanlarnn anahtarlarn kullanmamz gerekir.Burada anahtar, dizi elemannn sra numarasdr ve sra numaralar sfrdan balar, yani son dizi elemannn sra numaras dizi uzunluundan bir eksiktir.rnek olarak, az evvel oluturduumuz tekSayi dizisinin ikinci elemanna erielim:

>>> tekSayi[1]; 'Bir'


Pek ok kaynakta dizilerin u biimde tanmlandna rastlayabilirsiniz:

tekSayi = new Array("Bir","ki","");

Fakat grld gibi bu pratik bir tanmlama biimi deildir. Az evvel herhangi bir trde veri tutulabildiine deinmitik, bu konuda bir rnek hazrlamak iin, fonksiyon bilgimizi de kullanarak toplama ve karma yapan bir dizi oluturalm:

var islem = [ function(sayi0,sayi1){ return sayi0+sayi1; }, function(sayi0,sayi1){ return sayi0-sayi1; } ]


Oluturduumuz dizi birbirinden virglle ayrlm iki ayr fonksiyondan oluuyor, birinci dizi eleman toplama ilemi yaparken dieriyse karma ilemi yapyor.imdi bu dizinin elemanlarna tek tek eriip ilem yaptralm:

>>> islem[0](4,3) 7 >>> islem[1](4,3) 1


Diziler, Array snfndan trediinden tr, her dizi ayn zamanda alt method ve deerleri olan bir objedir.Ve doal olarak, dizi objeleri Array iskeletini tar ve bu iskelete serbeste ekleme/karma yaplabilir.Bu konuda daha detayl bilgi ve rnekler iin fonksiyonlar konusundaki prototype altbaln inceleyin. Dizi deerlerin mevcut alt methodlarn inceleyelim: concat ki veya daha fazla diziyi birletirmek iin kullanlr, rnek:

>>> ["deneme"].concat(["merhaba"],["dnya"]) ["deneme","merhaba","dnya"]


concat browser'n fazladan bir dizi daha oluturmasna neden olduundan pek tercih edilen salkl bir method deildir.Yerine daha kullanl olan "push" methodu kullanlilir.Birka balk sonra push methodunu inceleyeceiz.

join Verilen ayrac kullanarak diziyi string deere evirir.rnek,

>>> ["merhaba","dnya"].join("#") "merhaba#dnya" >>> ["merhaba","dnya"].join("!") "merhaba!dnya"


length Dizinin uzunluunu, yani ne kadar dizi eleman tuttuunu veren deer.rnek;

>>> var deneme = ["merhaba","dnya"] >>> deneme.length; 2


pop Dizinin son elemann siler ve sildii deeri dndrr.

>>> var deneme = ["merhaba","dnya"] >>> deneme.pop(); "dnya" >>> deneme ["merhaba"]
push Argman tnelinden gelen deerleri dizinin sonuna ekleyen method.Geriye dizinin yeni uzunluunu dndrr.

>>> var deneme = [] >>> deneme.push("merhaba","dnya"); 2 >>> deneme ["merhaba","dnya"]


Concat yerine Push methodunun kullanm

Push fonksiyonunu concat yerine kullanmak iin, fonksiyonlarn apply methodundan ve prototype objesinden faydalanlr.Bu iki konuda detayl bilgiyi fonksiyonlar balnda bulabilirsiniz.Gelelim rnee;

>>> var dizi1 = [1,2]; >>> var dizi2 = [3,4]; >>> var dizi3 = [5,6]; >>> var dizi4 = [7,8]; >>> dizi1.concat(dizi2); [1,2,3,4] >>> Array.prototype.push.apply(dizi3,dizi4); 4 >>> dizi3 [5,6,7,8]
rnekte concat methodunun kullanmn hatrladk ve ardndan apply methodunu ararak dizi3 ile dizi4 birletirdik. slice Dizi deerlerinin iinden istenen index aralklarn armay salar;

>>> [6, >>> [6, >>> [3,

[3,6,9,12].slice(1,3) 9] [3,6,9,12].slice(1,4) 9, 12] [3,6,9,12].slice(0,2) 6]

Blm Sonu Pratikleri


ECMAScript standartna gre, diziler ve nesneler farkl deikenlere aktarlamaz, referanslanr.Bunu daha iyi anlamak iin bir rnek yapalm:

>>> >>> >>> [3, >>> 4 >>> [3, >>> [3,

var a = [3,2,1]; var b = a; b 2, 1] b.push(0); b 2, 1, 0] a 2, 1, 0]

rnekte, b deerine ilk oluturduumuz a deerini atadmzda, iki deer birbirine referansland.Bunu anlamak iin b dizisine yeni bir say ekledik, a dizisini kontrol ettiimizde ayn saynn a'ya da eklendiini grdk.Aslnda b'ye eklendiimiz a'ya eklenmedi, daha dorusu biz hem a'ya hem b'ye ekleme yaptk. Bu zelliin at problemlerle ilgili bir rnek yapmak iin dizi tipinde alt deeri olan bir snf tanmlayalm:

>>> >>> [] >>> >>> >>> 1 >>> [1] >>> [1]

var deneme = function(){} deneme.prototype.dizi = []; var nesne1 = new deneme(); var nesne2 = new deneme(); nesne1.dizi.push(1); nesne1.dizi nesne2.dizi

rnekte grdnz gibi, deneme iskeletinden treyen tm objelerin dizi tipindeki alt deeri birbirine referansl.Biri deiince dieri de deimekte.imdi sorulara geelim: SORULAR Soru 1) Dizilerin klonlanmasn salayan, dizi.clone() eklinde altrlabilen bir method yazn.Dizilerin iie olabileini dikkate aln. Soru 2) Birinci sorunun cevabn, fonksiyonlarn iskeletinde yaanan referans probleminin zm iin uygulayn. CEVAPLAR Cevap 1) Bu problemin zm iin bu dkmanda bahsetmediim dngleri ve kontrol ifadelerini biliyor olmalsnz.Snflarn iskeletine method ekleme ilemi hakknda bilgi almak iin Fonksiyonlar konusundaki prototype balna dnn. Problemin cevabna geelim:

Array.prototype.clone = function(){ var gecici = []; for(var i=0; i<this.length; i++){ gecici.push( this[i] instanceof Array? this[i].clone():this[i] ); } return gecici;

}
rnekte, gecici adnda yeni bir dizi oluturduk ve dizi elemanlarn tek tek bu yeni diziye ekledik.Ve yeni diziyi geri dndrdk.Bu rnekteki en nemli satr, push fonksiyonuna veri gnderirken yaptmz kontrol:

this[i] instanceof Array? this[i].clone():this[i]


Eer dizinin eleman da bir diziyse, onu da klonlamamz gerekir.Bunun iin sradaki dizi deerinin Array snfndan treyip tremediini instanceof operatrn kullanarak kontrol ettik. Cevap 2) Eer iskelete dardan dizi deeri eklediysek, fonksiyonun constructor'nda bu deeri klonlamamz gerekir.

>>> var deneme = function(){ this.dizi = this.dizi.clone(); }

Nesneler: object
Objeler, tpk diziler gibi, istenen veri paralarn gruplayan veri trdr fakat dizi elemanlarnn aksine, nesnelerdeki elemanlar iin tantc belirlenir. Dizilerdeki keli parantezlerin yerini ssl parantezler alr.Nesne elemanlar birbirlerinden yine virglle ayrlrlar.Fakat bu kez her veri paras iin bir tantc belirlenir, bu ilem iin "var" ifadesi ve eit iareti kullanlmaz, tantc yazlp hemen ardnda ":" kullanlr. rnein,

>>> var merhaba = { ingilizce:"hello", ispanyolca:"holla" }


Nesnelerin elemanlar birer method olarak kabul edilir, dizilerde grlen arma ilemi dnda, dier programlama dillerindeki snf yaplarndan alk olduumuz method biimindeki arma ilemi de yaplabilir, her iki biimde de arma ilemi yapalm:

>>> merhaba.ingilizce hello >>> merhaba["ispanyolca"] holla


Method biimindeki arma ileminde tantcnn kullanm ekli zel karakter yazmna ve satrii dinamik kullanma uygun olmamas, dizi biimindeki tanmlamaNes eklinin nemini artrr;

>>> var meslekler = { "azer koulu":"renci", "nuray koulu":"retmen" }; >>> meslekler.azer koulu // hatal tantc yazdk. SyntaxError: missing ; before statement >>> meslekler["azer koulu"] renci
Nesne tanmlandktan sonra yeni bir eleman ekleme-karma ilemi yapmak iin dizilerdeki push ve pop fonksiyonlar yerine, yine dizilerden alk olduumuz tanmlama biimi kullanlr:

>>> var meslekler = { "azer koulu":"renci", "nuray koulu":"retmen" }; >>> meslekler["arda koulu"] = "renci"
Bu veri tipinin esnek yaps sayesinde, ECMAscript'in OOP eksiklii tamamlanr.Dizilerdeki basit ilem dizisini, nesneleri kullanarak tekrar yazalm:

>>> var islem = { topla: function(sayi0,sayi1){ return sayi0+sayi1; }, cikar: function(sayi0,sayi1){ return sayi0-sayi1; } } >>> islem.topla(2,3); 5 >>> islem.cikar(2,3); -1 >>> islem.cikar(islem.topla(2,3),1); 4
Yaptmz rnekte, "islem" adnda bir nesnenin iinde, fonksiyon tipinde "topla" ve "cikar" adlarn tayan iki method oluturduk, ve birka deerle test ettik. rnekteki kodlama trnn, ilem yaptrdmz deerleri gruplama dnda zel bir ilevi yok.Peki dier programlama dillerinde alk olduumuz "new" operatryle oluturulan (klonlanan da denilebilir) snflar oluturulamaz m? Elbette oluturulur, rnekten ilerleyelim:

>>> var islemci = function(sayi0){ return { topla: function(sayi1){

return sayi0+sayi1; }, cikar: function(sayi1){ return sayi0-sayi1; } } } >>> var islem1 = new islemci(5); >>> islem1.topla(3); // 5+3 = 8 8 >>> islem1.cikar(3); // 5-3 = 8 2
Uyguladmz son iki rnekteki farka dikkat edelim, ilk rnekte ilem yapan fonksiyon tipindeki verileri saklayan bir obje vard, ikinci rnekteyse, birinci rnekte saklanan objeyi "return" operatryle geriye dndren bir fonksiyon var. rnekteki "islem1", 'islemci`'nin argman tnelinden ald "5" deeri iin dndrd "topla" ve "cikar" fonksiyonundan oluan nesne deerini ald.Ardndaki satrlarda bu fonksiyonlar test ettik.

Blm Sonu Pratikleri


Diziler iin geerli olan referans problemi objeler iin de geerlidir.lk soru ayn konudan geliyor: SORULAR 1) Object fonksiyonunun altnda, argman tnelinden ald objeleri klonlayan Class adnda bir method yaratn.Eer objenin iindeki dizi deerleri varsa, onlar da klonlamay unutmayn.Zorlandnzda diziler konusundaki zmden faydalanabilirsiniz. 2) Obje dndren bir fonksiyon yaratn.Fakat bu objenin Init adnda bir methodu olsun ve fonksiyonun iinde dndrme ileminden nce alsn. CEVAPLAR 1)

Object.Clone = function(){ var gecici = []; for(var i=0; i<this.length; i++){ gecici.push( this[i] instanceof Array? this[i].clone():( typeof this[i]=="object"? Object.Clone(this[i]): this[i] ) ); } return gecici; }
Diziler balnda kullandmz klonlama fonksiyona bir kontrol daha ekledik:

typeof this[i]=="object"?Object.Clone(this[i]):this[i]
Burada aslnda deeri instanceof ile Obje snfndan treyip tremediini de kontrol edebilirdik.Fakat browser bu kontrolde fonksiyonlar iin de pozitif deer dndrecektir. 2) Bu problemin zm aslnda olduka basittir, objeyi nce tanmlar sonra return operatryle geri dndrrz.Fakat bu zm dnmeyi pek gerektirmez, biraz daha dnp daha iyi yntem bulmalyz.Bu tip kolay problemleri nasl daha pratik ekilde zebileceimizi, tekniimizi ilerletmek iin nemsemeliyiz.zme geelim:

function deneme(){ return ({ "Init": function(){ alert("Init fonksiyonundan merhaba!"); return this; } }).Init() }
Parantez bloklarn kullanarak biraz daha iyi bir zm kullandk.Buradaki zmn z Init fonksiyonunun iinde bulunduu objeyi dndrmesi. Fonksiyonlar, dizileri ve objeleri pekitirdiimize gre, leri OOP Teknikleri konusuna geebiliriz.

leri Seviye OOP Teknikleri


bu balk altndaki kod rneklerini ingilizce hazrladm.bunun sebebi kod standartlarn daha iyi anlamanz salamak Bu bala gelmeden nce, klasik obje yaplarn ve yeni poplerleen obje tekniklerini pratikletirdik.Neydi bu teknikler, birincisi fonksiyonlar balnda grdmz snf oluturma teknii.kincisi, objeler balnda incelediimiz, ok daha pratik olan snf oluturma teknii.Fonksiyonlar

balndaki yaplara tekrar gzatalm:

function deneme(){ this.zellik1 = deer; } var yeni = new deneme(); function deneme(){ } deneme.prototype.zellik1 = deer; var yeni = new deneme(); function deneme(){ } deneme.prototype = { "zellik1":deer; } var yeni = new deneme();
Objeler balndan karacamz yaplarsa unlar:

var deneme = { "zellik1":deer; } var yeni = Object.Clone(deneme); function deneme(){ return { "zellik1":deer } }
Her iki tekniin de profesyonel web projelerinin pek ounda kullanld grlr, ancak kod standartna gre yazm stilleri biraz daha deiim gsterecektir.rnek olarak u an altm irketin kod standartna gre bir snf oluturalm. Obje: Banka Hesab Deerler: ad soyad, bakiye, bor limiti lemler: Para Gnder, Para Yatr

function account(){ } account.prototype = { "_balance":0, "_limit":0, "_name":"", "getBalance":function(){ return this._balance; }, "setBalance":function(value){ this._balance = value; }, "getLimit":function(){ return this._limit; }, "setLimit":function(value){ this._limit = value; }, "getName":function(){ return this._name; }, "setName":function(value){ this._name = value; }, "SendMoney": function(value){ this.setBalance(this.getBalance()-value); }, "Invest":function(value){ this.setBalance(this.getBalance()+value); } }
Bu yazm biimini anlamaya alalm, neden deiken adlarnn nnde underscore iareti var? Neden her deiken iin get/set methodlar yazlyor? Underscore koymamzn nedeni browser'n reserveli kelimeleriyle akma olmamasn salamak.rnein "class" adnda bir deer oluturmamz gerekirse, webkit ve internet explorer yazdmz kodu durduracaktr.Bunun iin underscore ile iareti kullanrz. Peki, bir deeri isterken, veya ayarlarken, baka bir ilem yapmamz gerekiyorsa ne yaparz.Veya esas deeri, istenen ekle gre szerek vermemiz gerekiyorsa? Bu tip durumlarda standart bozulur, veya kodun ak deiir.Byle durumlar iin get/set zellikleri yazmak daha doru olacaktr.Peki, oluturduumuz bu objede get ve set fonksiyonlar iinde szme vb. ilemler yaplyor mu? Hayr.Bu unsuru aklmzda tutalm, birazdan tekrar dneceiz.

Son iki satrda ilem yapan fonksiyonlar, ba harfleri byk ekilde yazdk.nk ortam deerlerinden ayrlmalar gerekiyordu. Elimizde iki nemli unsur var: birincisi nemsiz yere get ve set kullanmamak.Yani gerektiinde yazmalyz.Fakat yazmasak ta standart bozulmamal, makine kendisi bizim yerimize rutin ilemleri yerine getirmeli.Dier husus, ilem yapan fonksiyonlar ortam deerlerinden ayrmak.Bu iki unsuru toparlarsak nasl bir obje yapsna ihtiyacmz olduuna karar verelim.Genel kullanm ekli yle olsun:

var azer = new account(); azer.environment.setName("Azer Koulu"); azer.environment.setBalance(1000); azer.environment.setLimit(2000); // ilem yapan fonksiyonlar kullanalm: azer.sendMoney(500);
rnekte grdnz gibi, ortam deikenlerini alt objeye yerletirerek ilem yapan fonksiyonlardan arndrp biraz daha dzenledik. Bu kullanm rneinden ilerlemek istediimizde karmza kacak ilk sorun, environment objelerinin referanslanarak birbirine bal hale gelmesidir.Sadece environment objesini dnmeyelim, normalde prototype zerinden snf oluturmaya altmzda, dizi ve obje tr deerlerin hepsi birbirine referanslanacak ve programmz bozacaktr. Bu problemleri amak iin istediimiz gibi snf oluturmamz salayan bir arabirim gereklidir.

Blm Sonu Pratii


Her snfn Constant,Environment,Event adnda alt objeleri olmal.Program yazarken, sabitleri, ortam deikenleri ve event yakalayclar bu ekilde ayrmalyz.Ve tabii, gerek olmadnda get/set yazmamalyz, bizim yazmadmz get ve set methodlarn kod standartnn bozulmamas iin program bizim yerimize oluturmal.En nemlisi de, yapacamz arabirim referans problemini otomatik olarak zmeli.Arabirimin rnek kullanmn inceleyin:

var account = new Interface; account.body = { "Invest":function(){ }, "SendMoney":function(){ } } account.environment = { "_balance", "_limit", "_name" } account = account.build();
Bu rnee ek olarak, extend ve constructor adl iki methoda ihtiyacmz var.extend, oluturacamz snf baka bir snf kapsyorsa kullanacamz method olacak.consturctor ise, oluturacamz snfn constructor' olacak.Bu noktada obje referans problemini constructor'da zdmz hatrlamalsnz. Okuduunuz dkman bu snf yazabilmenizi salamaya alt.Bu pratii yaparken kod standartnz gelitireceinize inanyorum, umarm dkman faydal olmutur. Sorunun cevabn m merak ediyorsunuz :) Interface adn verdiim snf, hazrladm Pi adl javascript ktphanesi iin yapmtm.te kodlar:

var interface = function(){ this.constants = {}; this.environment = {}; this.events = {}; this.body = {}; } interface.prototype = { "constant":{}, "constructor":function(){}, "environment":{}, "event":{}, "body":{}, "extend":function(OBJECT){ var body = Object.Clone(OBJECT.prototype); Object.Concat(this.body,body); Object.Concat(this.constants,body.constants); Object.Concat(this.environment,body.environment); Object.Concat(this.event,body.event); }, "build":function(){ var link = this; var fn = function(){ this.constants = Object.Clone(this.constants); this.environment = Object.Clone(this.environment); this.environment._parent_ = this; this.event._parent_ = this; link.constructor.apply(this,arguments); };

for(var item in this.environment){ if(item.substring(0,1)!="_")continue; var name = item, title = name.substring(1,2).toUpperCase()+name.substring( if(Boolean(this.environment["get"+title])==false) this.environment["get"+title] = new Function("return this."+name); if(Boolean(this.environment["set"+title])==false) this.environment["set"+title] = new Function("VALUE","this."+name+ } this.body.constants = this.constants; this.body.environment = this.environment; this.body.event = this.event; fn.prototype = this.body; return fn; } };
Sizin iin faydal bir dkman olduunu umut ediyorum.Sabrnzn ve gayretinizin karln almanz dilerim. Azer Koulu

You might also like