ECMAScript Nesne Değiştirme

ECMAScript kullanılarak, sadece nesneler oluşturulabilir, aynı zamanda mevcut nesnelerin davranışları da değiştirilebilir.

prototype özelliği, yapıcı fonksiyonun özelliklerini ve yöntemlerini tanımlamakla kalmaz, aynı zamanda yerel nesnelere özellikler ve yöntemler eklemek için de kullanılır.

Yeni yöntem oluşturma

Mevcut yöntemlerle yeni yöntem oluşturma

Prototype özelliği ile herhangi bir mevcut sınıfa yeni yöntemler tanımlayabilirsiniz, kendi sınıfınız gibi işlem yapabilirsiniz. Örneğin, Number sınıfının toString() yöntemini hatırlıyor musunuz? Eğer ona 16 parametresi ile verirseniz, onaltılık bir dize çıktısı verir. Eğer bu yöntemin parametresi 2 ise, ikili dize çıktısı verir. Bu yöntemi kullanarak bir numara nesnesini doğrudan onaltılık dizeye dönüştürebilecek bir yöntem oluşturabilirsiniz:

Number.prototype.toHexString = function() {
  return this.toString(16);
};

Bu ortamda, anahtar kelime this Number sınıfının bir örneğine işaret eder, bu yüzden Number'in tüm yöntemlerine tam erişim sağlar. Bu kod ile aşağıdaki işlemleri gerçekleştirebilirsiniz:

var iNum = 15;
alert(iNum.toHexString());		// "F" çıktısı

TIY

Sayı 15, onaltılıkta F'ye eşittir, bu yüzden uyarı "F" olarak görüntülenir.

Mevcut yöntemleri yeniden adlandırma

Ayrıca, mevcut yöntemlere daha anlaşılır isimler de verebiliriz. Örneğin, Array sınıfına enqueue() ve dequeue() iki yeni yöntem ekleyebiliriz, sadece mevcut push() ve shift() yöntemlerini tekrar çağırırlar:

Array.prototype.enqueue = function(vItem) {
  this.push(vItem);
};
Array.prototype.dequeue = function() {
  return this.shift();
};

TIY

Mevcut yöntemlerle ilgili olmayan yöntem ekleme

Tabii ki, mevcut yöntemlerle ilgili olmayan yöntemler de ekleyebilirsiniz. Örneğin, bir öğenin dizideki konumunu belirlemek için mevcut bir yöntem yoksa, aşağıdaki yöntemi kolayca oluşturabiliriz:

Array.prototype.indexOf = function (vItem) {
  for (var i=0; i<this.length; i++) {
    if (vItem == this[i]) {
	  return i;
	}
  }
  return -1;
}

Bu yöntem indexOf() String sınıfının aynı adlı yöntemle aynı kalır, dizide her bir öğeyi tarar ve gelen öğe ile aynı olan öğeyi bulana kadar. Eğer aynı olan bir öğe bulursanız, o öğenin konumunu döndürür, aksi takdirde -1 döndürür. Bu tanımlama ile, aşağıdaki kodu yazabiliriz:

var aColors = new Array("red","green","blue");
alert(aColors.indexOf("green"));	// çıktı "1"

TIY

Yerel nesnelere yeni yöntem eklemek

Son olarak, ECMAScript'teki her yerel nesneye yeni bir yöntem eklemek için, bu yöntemi Object nesnesinin prototype özelliğinde tanımlamak zorundasınız. Önceki bölümlerde belirtildiği gibi, tüm yerel nesneler Object nesnesini miras alır, bu yüzden Object nesnesine herhangi bir değişiklik, tüm yerel nesnelere yansır. Örneğin, nesnenin mevcut değerini uyarı ile çıktılamak için aşağıdaki kodu kullanabilirsiniz:

Object.prototype.showValue = function () {
  alert(this.valueOf());
};
var str = "hello";
var iNum = 25;
str.showValue();		// çıktı "hello"
iNum.showValue();		// çıktı "25"

TIY

Burada, String ve Number nesneleri showValue() yöntemini Object nesnesinden miras alır, bu yöntemi nesneler üzerinde çağırarak "hello" ve "25" görüntülenir.

Mevcut yöntemleri yeniden tanımlama

Mevcut sınıflara yeni yöntemler ekleyebildiğiniz gibi, mevcut yöntemleri de yeniden tanımlayabilirsiniz. Önceki bölümlerde belirtildiği gibi, fonksiyon adı sadece fonksiyona işaret eden bir işaretçidir, bu yüzden kolayca başka bir fonksiyona işaret edebilir. Yerel bir yöntemi, örneğin toString(), değiştirdiğinizde ne olur?

Function.prototype.toString = function() {
  return "Function code hidden";
}

Önceki kod tamamen meşru, çalıştırma sonucu beklediğiniz gibi

function sayHi() {
  alert("hi");
}
alert(sayHi.toString());	// çıktı "Function code hidden"

TIY

Belki hala hatırlıyorsun, Function nesnesi bölümünde tanıtılan Function'ın toString() yöntemi genellikle fonksiyonun kaynak kodunu çıktı verir. Bu yöntemi geçersiz kılmak, başka bir dize döndürebilir (bu örnekte, "Function code hidden" dizesi döndürülebilir). Ancak, toString() yöntemi işaret ettiği orijinal fonksiyon ne oldu? Tamamen terk edildiği için atık bellek birimi geri dönüşüm programı tarafından geri alınacak. Orijinal fonksiyonu geri yükleyemeyen bir yöntem yok, bu yüzden orijinal yöntemi geçersiz kılmadan önce, onun işaretini saklamak daha güvenlidir. bazen yeni yönteminde orijinal yöntemi çağırabilirsiniz:

Function.prototype.originalToString = Function.prototype.toString;
Function.prototype.toString = function() {
  if (this.originalToString().length > 100) {
    return "Fonksiyon görüntülenemiyor kadar uzun.";
  } else {
    return this.originalToString();
  }
};

TIY

Bu kod parçasında, ilk satırda mevcut toString() yöntemine olan atıf, originalToString adlı bir özelliğe saklanır. Daha sonra özelleştirilmiş bir yöntemle toString() yöntemini geçersiz kılar. Yeni yöntem, fonksiyonun kaynak kodunun uzunluğunu 100'den büyük olup olmadığını kontrol eder. Eğer büyükse, fonksiyonun kodunun çok uzun olduğunu belirten bir hata mesajı döner, aksi takdirde originalToString() yöntemini çağırır ve fonksiyonun kaynak kodunu döner.

Çok geç bind (Very Late Binding)

Teknik olarak, çok geç bind yoktur. Bu kitap, ECMAScript'teki bir fenomeni tanımlamak için bu terimi kullanır, yani nesne örneklenmeden sonra yöntemlerini tanımlayabilir. Örneğin:

var o = new Object();
Object.prototype.sayHi = function () {
  alert("hi");
};
o.sayHi();

TIY

Çoğu programlama dilinde, nesneleri örneklenmeden önce nesnelerin yöntemleri tanımlanmalıdır. Burada, method sayHi() Object sınıfının bir örneği oluşturulduktan sonra eklenmiştir. Geleneksel dillerde bu tür bir işlem duyulmamış ve bu yöntemin Object nesnesinin örneklerine otomatik olarak atanıp hemen kullanılabileceğini duymamışızdır (bir sonraki satır).

Dikkat:Çok geç bind metotları kullanılmamalıdır, çünkü izlenmesi ve kaydedilmesi zor olur. Ancak, bu olasılığı anlamak hala önemlidir.