Javascript ile Nesne Yönelimli Programlama (OOP with JS)

Bu makalede Javascript’le ilgili olarak JSON, function pointer ve OOP konuları ele alınıyor
Çoğu programcı tarafından önemsiz görülmek, ara-bul-kopyala-yapıştır ile kullanılmak Javascript’in neredeyse kaderi olmuştur. Nedense programcılar, kodlama zamanlarının büyük bir kısmını user interface tarafında taklalar atmakla geçirmelerine rağmen bu user interface dilini önemsememişlerdir. Aslında, bir uygulamanın user interface katmanını programlamak iş mantığı katmanını programlamaktan daha zordur. Çünkü iş mantığı daha prosedürel, kuralları daha belli olma eğilimindedir. User interface ise müşterinin en çok müdahele ettiği, en çok değişikliğe uğrayan, zamanla büyüyen, kompleksleşen ve yönetilemez hale gelen kısımdır.
Önceleri Javascript çoğu web sitesinde bir takım UI işlemleri ve form validation gibi basit amaçlar için kullanılırdı. Web programcıları daha çok ASP, PHP gibi server tarafındaki dillere odaklanır, Javascript’i -çok afedersiniz- iplemezlerdi. Bugün ise Javascript, Ajax ile daha güçlü ve daha ilgi çekici hale gelmiştir. Çünkü artık web uygulamalarında da -desktop uygulamalarda olduğu gibi- rich user interface mümkün hale gelmiştir. Gerçi bu tamamen DHTML ile ilgili bir konu olsa da Ajax bunu daha anlamlı hale getirdi. Artık client tarafında da nesne yönelimli ve katmanlı kodlama yapmanın mümkün olduğunu biliyoruz. Javascript eskisinden çok daha saygın bir dil. Ve artık her geçen gün insanlar Internet üzerinde yeni Ajax destekli Javascript frameworkleri geliştiriyor, yayınlıyor.
Bu makalemizde Javascript bilgilerimizi tekrar gözden geçirecek, özellikle de Javascript’in OOP yönüne eğileceğiz.
JSON
Öncelikle JSON’dan (ceysın) bahsederek konuya girmek istiyorum. AJAX’ın yükselişiyle birlikte geliştirilen frameworklerde, fonksiyonların parametrelerinde dahi görmeye başladığımız bu sentaks, Javascript’de bir nesne oluşturmanın kolay bir yolundan başka bir şey değildir. Biraz XML’i andırır ama aslında dilin bir parçasıdır ve XML’de olduğu gibi programcı tarafından parse edilmesi gerekmez. Hemen bir örnekle inceleyelim:
var kopegim = {
renk : ‘siyah’,
yas : 2,
havla : function(havlamaSayisi)
{
for(i=0; i<havlamaSayisi; i++)
alert(‘hav’);
}
}
Şu an iki property ve bir methoda sahip bir nesne oluşturduk ve kopegim değişkeni bu nesnenin referansı oluyor. JSON ile süslü parentezler arasında, virgüllerle ayırarak property’ler ve metodlar oluşturmak gördüğünüz gibi gayet kolay. Bu nesnemizi aşağıdaki gibi kullanabiliriz:
alert(‘Köpeğim ‘ + kopegim.yas + ‘ yaşında’);
kopegim.havla(3);
Fonksiyon nesneleri
Javascript’te fonksiyonlar da aslında birer nesnedir. Özelliklere ve metodlara sahip olabilirler, başka fonksiyonlara parametre olarak gönderilebilirler. Fonksiyonların parametre olarak başka fonksiyonlara gönderilmesini -ki bunlara callback function denir- aşağıdaki örnekte inceleyelim:
var kopegim = {
havla : function() { alert(‘hav’); }
}
var kedim = {
miyavla : function() { alert(‘miyav’); }
}
function hayvaniRahatsizEt(hayvanSesFonksiyonu)
{
hayvanSesFonksiyonu();
}
hayvaniRahatsizEt(kopegim.havla);
hayvaniRahatsizEt(kedim.miyavla);
kedim.miyavla = kopegim.havla;
hayvaniRahatsizEt(kedim.miyavla); // burada kedimiz havlayacak!
Dikkat ettiyseniz bir fonksiyonu başka bir fonksiyona parametre olarak gönderirken ya da bir fonksiyonu diğerine atarken parantezleri “()” kullanmıyoruz. Çünkü parantezler olmadığı zaman fonksiyonlara nesne olarak erişmiş oluruz. (function pointer) Parantezler olduğu zaman ise fonksiyon çalıştırılır ve geri dönen değeri parametre olarak geçilir ya da atanır. (Yukarıdaki örneklerde geri dönen değer undefined’dır.)
Aslında Javascript’de diziler ve nesneler birbirinden pek ayırdedilmezler. Örneğin;
degisken = {} // yeni bir nesne ortaya çıkartır.
degisken[‘birDeger’] = 10;
degisken[‘birFonksiyon’] = function(){ alert(‘bisey’); };
tanımlaması ile
degisken = {
birDeger: 10,
birFonksiyon: function(){ alert(‘bisey’); }
}
tanımlaması aynı işi görür. Sadece kullanımları biraz farklıdır. Birincisinde fonksiyon:
degisken[‘birFonksiyon’]();
ile çağrılırken, ikincisinde
degisken.birFonksiyon();
ile çağrılır.
Javascript’te sınıf tanımlamak
Javascript’te sınıf tanımlamanın sentaksı diğer dillerden biraz farklıdır. Sınıf tanımlama işlemini bir çeşit constructor metodla yaparız. Aşağıdaki örneği inceleyelim.
// Kedi isimli bir sınıf tanımlayalım
var Kedi = function(ad, yas) // Kedi sınıfının constructor’ı.
{
this.ad = ad; // ad adında bir property ekledik
this.yas = yas; // yas adında bir property ekledik
this.miyavla = miyavlaFonksiyonu; // miyavla adında bir method ekledik
}
function miyavlaFonksiyonu() // bu fonksiyon aslında Kedi sınıfına ait
{
alert(‘Benim adım ‘ + this.ad + ‘. Miyaaav’);
}
// şimdi bu sınıfı kullanalım
kedim = new Kedi(‘pamuk’, 2); // new keyword’ü ile instance oluşturuyoruz
alert(“Kedim: ” + kedim.ad); // yeni kedimizin ad property’sine eriştik
kedim.miyavla(); // “Benim adım pamuk. Miyaaav” der.
miyavlaFonksiyonu(); // “Benim adım undefined. Miyaaav” der. Neden undefined?
Tam olarak bir class yapmak istersek şunu kullanabiliriz
var Kedi = function(ad, yas) // Kedi sınıfının constructor’ı.
{
this.ad = ad; // ad adında bir property ekledik
this.yas = yas; // yas adında bir property ekledik
this.miyavla = function(){
alert(‘Benim adım ‘ + this.ad + ‘. Miyaaav’);
} // miyavla adında bir method ekledik
}
// şimdi bu sınıfı kullanalım
kedim = new Kedi(‘pamuk’, 2); // new keyword’ü ile instance oluşturuyoruz
alert(“Kedim: ” + kedim.ad); // yeni kedimizin ad property’sine eriştik
kedim.miyavla(); // “Benim adım pamuk. Miyaaav” der.
kedim2 = new Kedi(‘boncuk’, 3); // ikinci kedimizi oluşturuyoruz
alert(“2. Kedim: ” + kedim2.ad); // “Benim adım boncuk” der.
Bu sınıfın constructor’ına yeni property ve methodlar ekleyerek sınıfımızı geliştirebiliriz. Tam burada Javascript’in çok güçlü bir özelliğinden bahsetmek istiyorum. Bir sınıfa yeni metod ve özellikler eklemek için sadece constructor’ı kullanmak zorunda değiliz. Bunun yerine bütün sınıfların default sahip olduğu prototype isimli özelliği kullanabiliriz. Prototype -adı üzerinde- bir sınıfın sahip olduğu özellik ve metodların referanslarına sahip bir özellik olması ile sınıfın prototipini tanımlar. Bu özelliğe yeni bir metod eklemek, o metodu aslında sınıfa eklemek anlamına gelir. Buna prototype based programming (prototip tabanlı programlama) denir. Bu sayede Javascript’de zaten var olan String, Number, Array gibi sınıfları dahi genişletebiliriz. Şimdi yukarıdaki Kedi sınıfının prototype’ını kullanarak bir özellik ve metod ekleyelim:
Kedi.prototype.cinsi = undefined;
Kedi.prototype.havla = function() {
alert(“Ben kediyim havlamam ki! Cinsim ” + this.cins);
}
kedim.cinsi = “Van kedisi”; // kedim’ize yeni özelliğini tanımlayalım
kedim.havla(); // kedim’izi havlatalım
Yukarıdaki Kedi sınıfını JSON ile çok daha şık bir şekilde tanımlayabiliriz. Bunun için Class isimli yardımcı sınıfın create metoduyla sınıfımızı oluşturacak ve prototype’ını direk JSON ile set edeceğiz:
var Kedi = Class.create();
Kedi.prototype = {
initialize: function(ad, yas) {
this.ad = ad;
this.yas = yas;
},
miyavla : function() {
alert(‘Benim adım ‘ + this.ad + ‘. Miyaaav’);
},
cinsi : undefined,
havla : function() {
alert(“Ben kediyim havlamam ki! Cinsim ” + this.cinsi);
}
}
kedim = new Kedi(‘pamuk’, 2); // new keyword’ü ile instance oluşturuyoruz
alert(“Kedim: ” + kedim.ad); // yeni kedimizin ad property’sine eriştik
kedim.miyavla(); // “Benim adım pamuk. Miyaaav” der.
kedim.cinsi = “Van kedisi”; // kedim’ize yeni özelliğini tanımlayalım
kedim.havla(); // kedim’izi havlatalım
// Bu satırı şimdilik dikkate almasanız da olur ama yukarıdaki gibi sınıf tanımlayabilmek için gerekli.
var Class = { create: function() { return function() { this.initialize.apply(this, arguments); } } };
Bu makalemizde Javascript’le ilgili olarak JSON, function pointer ve OOP’dan bahsettik. Tabi OOP sadece öezellik ve metodları olan sınıflar demek değildir, inheritance vb. konuları da incelemek gerekir. İnşallah onu da başka bir zaman inceleriz.
Kaynak www.bilisim-kulubu.com/makale/makale.php