JavaScript Temelleri

Bölüm 15

Kullanıcı Tanımlı Nesneler

Bölüm 15 Sayfa 2

15.2 - Kullanıcı Tanımlı Nesnelerin Yapılandırılması

15.2.1 - Kullanıcı Tanımlı Nesnelerin Prototip Arttırımı Yöntemi İle Yapılandırılması

Kullanıcı tanımlı nesne sınıflarında, kullanıcılar oluşturacakları nesne sınıflarının yapısını düzenleyip, sınıfın prototipine yerleştirmek zorundadır. Nesne sınıfının prototipinde bulunmayan hiçbir özellik, oluşan nesne sınıf örneğinde başlangıçta bulunamaz.

Nesne özelliklerinin prototiplerine kullanıcılar tarafından katkıda bulunabileceği bundan önce birçok kez açıklanmıştı. Bu konu en son biraz önce bölüm 15.1.3 de nesne hiyerarşileri incelendiğinde yeniden ele alınmıştı. Kullanıcı tanımlı nesne sınıflarının yapılarının prototip katkısı ile oluşturulması geçerli bir yöntemdir. Nesne sınıfı veri giriş fonksiyonu boş olarak tanımlandıktan sonra, her özellik için, sadece bir kez, prototip katkısı yapılması yeterlidir. Sonuçta, sınıfın prototipinin yapısı belirlenmiş olur. Bu yöntem bir JavaScript programında uygulanmıştır. Bu programın bağlantılı olduğu uygulama sayfasında, verdiği sonuç, aşağıda görülmektedir:

...

function Kutu() {
}

function hacım() {
var v = this.en * this.boy* this.yükseklik;

return v / 1000 + 'litre';
}

Kutu.prototype.en = 0;

Kutu.prototype.boy = 0;

Kutu.prototype.yükseklik = 0;

Kutu.prototype.hacım = hacım;


var kutu1 = new Kutu();

kutu1.en = 10;

kutu1.boy = 20;

kutu1.yükseklik = 20;

sonuçYaz('kutu1 Hacmı = ', kutu1.hacım(), 'b15.2.1-uyg-1-sonuç-1');

...
		

Program Sonucu :

Yukarıdaki, yöntemde herşey iyi yürümektedir. Sorun sadece, yeni oluşturulan nesne örneklerinin öntanımlı değerlerle oluşmalarıdır. Her defasında bu örneklere özellik değerlerinin girilmesi gerekecektir. Bu da biraz sıkıcı bir veri giriş yöntemi sayılabilir. Bu sorunu azaltmak için, çeşitli formlar, nesne örneği veri giriş fonksiyonları yazılabilir. Bu tip bir nesne örneği veri giriş fonksiyonu, aşağıda görülen programda uygulanmış ve programın iliştirildiği sayfada verdiği sonuç, aşağıda gösterilmiştir.

...

function Kutu() {
}

function hacım() {
var v = this.en * this.boy* this.yükseklik;

return v / 1000 + 'litre';
}

function prototipOluştur() {

Kutu.prototype.en = 0;

Kutu.prototype.boy = 0;

Kutu.prototype.yükseklik = 0;

Kutu.prototype.hacım = hacım;

}

prototipOluştur();

function kutuSınıfÖrneğiVeriGirişi(kutuSınıfÖrneğiAdı, eni, boyu, yüksekliği) {

if (!(kutuSınıfÖrneğiAdı instanceof Kutu)) {
kutuSınıfÖrneğiAdı = new Kutu();
}

kutuSınıfÖrneğiAdı.en = eni;

kutuSınıfÖrneğiAdı.boy = boyu;

kutuSınıfÖrneğiAdı.yükseklik = yüksekliği;
}


var kutu2 = new Kutu();

kutu2 = kutuSınıfÖrneğiVeriGirişi(kutu2, 20, 30, 20);

sonuçYaz('kutu2 Hacmı = ', kutu2.hacım(), 'b15.2.1-uyg-2-sonuç-1');

...
		

Program Sonucu :

Yukarıdaki uygulamada, nesne örneği veri giriş fonksiyonuna, aktarılan ilk argümanın gerçek bir Kutu sınıfı nesne örneği olmaması durumunda, fonksiyon bu argümanın değerini tahrip edici bir atama ile, gerçek bir Kutu sınıf örneğine dönüştürmektedir. Fonksiyonun bundan sonraki görevi, oluşmuş olan Kutu sınıfı nesne örneğinin özelliklere verilen argümanların değerlerinin atanmasıdır. Fonksiyon, sonuçta veri girişi tamamlanmış Kutu sınıf örneğini geri döndürmektedir.

Nesne örneği veri giriş fonksiyonun, aktarılan ilk argümanın değerinin bir Kutu sınıf örneği olmasını şart koşmamaktadır. Bu yüzden aşağıda görülen JavaScript programında olduğu gibi, nesne örneğinin de nesne örneği veri giriş programı tarafından oluşturulması sağlanabilir. Biraz daha kısalan bu programın bir uygulama sayfasında verdiği sonuç, aşağıda görülmektedir:

...

function Kutu() {
}

function hacım() {
var v = this.en * this.boy* this.yükseklik;

return v / 1000 + 'litre';
}

function prototipOluştur() {

Kutu.prototype.en = 0;

Kutu.prototype.boy = 0;

Kutu.prototype.yükseklik = 0;

Kutu.prototype.hacım = hacım;

}

prototipOluştur();

function kutuSınıfÖrneğiVeriGirişi(kutuSınıfÖrneğiAdı, eni, boyu, yüksekliği) {

if (!(kutuSınıfÖrneğiAdı instanceof Kutu)) {
kutuSınıfÖrneğiAdı = new Kutu();
}

kutuSınıfÖrneğiAdı.en = eni;

kutuSınıfÖrneğiAdı.boy = boyu;

kutuSınıfÖrneğiAdı.yükseklik = yüksekliği;
}


var kutu3 = kutuSınıfÖrneğiVeriGirişi(kutu3, 20, 30, 20);

sonuçYaz('kutu3 Hacmı = ', kutu3.hacım(), 'b15.2.1-uyg-3-sonuç-1');

...
		

Program Sonucu :

Bazı durumlarda, öntanımlı değerlerden farklı olarak, bazı standart değerler de verilmek istenebilir. JavaScript programlama dilinde, bu işlevi sağlayabilecek bir olanak bulunmaktadır. Bu tür esnek bir veri giriş fonksiyonu aşağıda verilmiştir. Bu fonksiyonun ilişkli olduğu sayfada verdiği sonuçlar, aşağıda görülmektedir:

...
function kutuSınıfÖrneğiVeriGirişi(kutuSınıfÖrneğiAdı, eni, boyu, yüksekliği) {

if (!(kutuSınıfÖrneğiAdı instanceof Kutu)) {
kutuSınıfÖrneğiAdı = new Kutu();
}

kutuSınıfÖrneğiAdı.en = eni || 10;

kutuSınıfÖrneğiAdı.boy = boyu || 10;

kutuSınıfÖrneğiAdı.yükseklik = eni || 10;
}


var kutu4 = kutuSınıfÖrneğiVeriGirişi(kutu4, null, 30);

sonuçYaz('kutu4 Hacmı = ', kutu4.hacım(), 'b15.2.1-uyg-4-sonuç-1');

...
		

Program Sonucu :

Yukarıdaki uygulamada, fonksiyon içinde özellik değeri atanırken ilk olarak argümanın sağladığı özellik değerine bakılmaktadır. Bu değer, undefined veya null ise, || işlemcisi sağ tarafı değerlendirerek 10 değerini atamaktadır. Burada argümanda sözel bir değer de varsa argüman atanır ve sözel değer sayıya çözümlenemezse sonuç NaN olarak görüntülenir. Yani bu ifade şekli, yanlış değerler girilirse bir kurtarma yöntemi olamaz. Sadece pas geçmek istenen argümanların yerine örnekteki gibi null yazılırsa, OR işlemcisi sağ işleneni değerlerdirir ve çözümlenen değeri özelliğe atar. Yine örnekteki gibi, en son argüman pas geçilmek isteniyorsa, hiçbirşey yazılmaz. Örnekteki sonuç, 10 X 30 X 10 luk (cm olmalı çünkü sonuç litre olarak veriliyor) bir kutunun hacmıdır.

Örnekteki hacım() metodunda this saklı sözcüğü, daha önce bölüm 2.6.3 de kısa olarak açıklanmıştı. Metotlardaki this saklı sözcüğü, metodu çağıran nesnenin yerine geçer. Bu durumda, hacım metodunu Kutu sınıfı nesne örnekleri çağırdığından, metodu çağıran her Kutu sınıfı nesne örneği, this saklı sözcüğü ile yer değiştirir. Örnek olarak, hacım metodunu, kutu1 adlı Kutu sınıfı nesne örneği çağırırsa, this.en , kutu1.eb anlamına gelir. this saklı sözcüğü çok güçlü bir programlama aracıdır, fakat değişik durumlarda değişik anlamlar alabilmektedir. Dolayısı kullanımı için, variyasyonlarına iyi hakim olunması gerekmektedir. Bu nedenle ileride, this saklı sözcüğü üzerinde daha ayrıntılı olarak duracağız.

Nesne örneklerini oluşturup, özelliklerine verilerin atanmasını kolaylaştıran veri giriş fonksiyonlarının işlevleri sadece yapısı belli olan sınıf örneklerinin özelliklerine değerler atamaktır. Eğer, bu işlevin sınırları aşılır ve veri giriş fonksiyonunda, nesnenin prototipinde olmayan özelliklerin de tanımlanıp değerlerinin girilmesi yoluna gidilirse, sorun yaratılmış olur. Bu durumda, sınıf yapılandırıcı fonksiyonu olan örnek olarak Kutu() fonksiyonu kullanılarak yaratılan nesne sınıf örnekleri ile, veri giriş fonksiyonunda özellikleri arttırılarak yaratılan nesne sınıf örnekleri arasında yapı farkı oluşur. Nesne Yönelimli Programlama düzen demektir. Bir sınıf örnekleri arasında yapı düzensizliği oluşması, sınıf üyelerinin integritesinin kaybolmuş olması anlamına gelir. Bu durumda, sınıfın prototipal yapısı gözetilerek oluşturulmuş otomatizasyon programları, bir kısım sınıf örnekleri ile uyumsuz hale gelir. Bu nedenle dikkatli olunmalı ve sınıf örneklerinin bazılarına gerekli olmaya başlayan her türlü yeni özellik, nesne sınıfının prototipine eklenmeli, o vakte kadar yaratılmış nesne örneklerinin (ki nesne sınıf örnekleri genellikle diziler halinde organize edilip disklerde saklanırlar), çağrılıp, bilinçli uyum programları ile yapılarının güncellenmesi gerekir. Bunun dışında, tek nesne örneklerine eklenecek özellikler, ayrıca eklenmeli, aynı özelliği birden . çok nesne örneğine kaydedecek veri giriş fonksiyonları ile eklenmemelidir. Veri giriş fonksiyonları, sadece nesne sınıfının prototipine işlenmiş özelliklerin değerlerini nesne sınıf örneklerine atamakla sınırlı kalmalıdır.

Yukarıdaki uygulamalara bakıldığında, özellikle nesne özelliklerine veri girişi yapmayı kolaylaştıran fonksiyonlar geliştirildiğinde, Kutu nesne sınıfına gerek olmadığı ve aynı işlerin generik nesne sınıfının aynı özellikli örnkeleri ile de yapılabileceği görülür. Bu konuda bir JavaScript programı ve bağlantılı olduğu uygulama sayfasında verdiği sonuç, aşağıda görülmektedir:

...

function hacım() {
var v = this.en * this.boy* this.yükseklik;

return v / 1000 + 'litre';
}


function kutuÖrneğiVeriGirişi(kutuÖrneğiAdı, eni, boyu, yüksekliği) {

if (!(kutuÖrneğiAdı instanceof Kutu)) {
kutuÖrneğiAdı = new Object();
}

kutuÖrneğiAdı.en = eni || 10;

kutuÖrneğiAdı.boy = boyu || 10;

kutuÖrneğiAdı.yükseklik = yüksekliği || 10;

kutuÖrneğiAdı.hacım = hacım;
}

var kutu5 = kutuÖrneğiVeriGirişi(kutu5, 10, 30, 10);
sonuçYaz('kutu5 Hacmı = ', kutu5.hacım(), 'b15.2.1-uyg-5-sonuç-1');

...
				

Program Sonucu :

Yukarıdaki uygulamadan da görüldüğü gibi, eşdeğer sonuçlar, yeni bir Kutu nesne sınıfı tanımlanmasına gerek olmadan nesne literalleri ile de alınabilmektedir. Buna rağmen, nesne literalleri, birbirine benzemez, tek olan nesne örnekleri için uygundur. Aynı yapıyı paylaşan çok sayıda potansiyel örnek bulunuyorsa, bunların ayrı bir sınıf halinde organize edilmeleri daha doğru olacaktır. Ayrı bir sınıf olunca, sınıfın bir prototipi olacak, sınıfların çalışmasını kolaylaştıran bazı öntanımlı yardımcı fonksiyonlardan yararlanılabilecek ve en önemlisi, sınıfın kendi yapılandırıcı fonksiyonu olacaktır. Ayrıca, bir sınıf olarak tanımlanınca, bu sınıfın alt sınıfları da tanımlanabilecektir.

Valid XHTML 1.1