
JavaScript’te Prototypal Inheritance (Prototip Tabanlı Kalıtım)
JavaScript, nesne tabanlı bir dil olup, nesneler ve kalıtım ile çalışmak için çeşitli yöntemler sunar. Ancak JavaScript’in diğer nesne tabanlı dillerden farklı olarak kullandığı Prototypal Inheritance (prototip tabanlı kalıtım) mekanizması, JavaScript öğrenmeye yeni başlayanlar için bazen kafa karıştırıcı olabilir. Bu yazıda, prototip tabanlı kalıtımın ne olduğunu, nasıl çalıştığını, nasıl kullanılacağını ve diğer kalıtım yöntemlerinden farklarını inceleyeceğiz.
Prototypal Inheritance Nedir?
Prototypal Inheritance, JavaScript’te bir nesnenin diğer nesnelerin özelliklerini ve metotlarını devralmasını sağlayan bir mekanizmadır. Yani, bir nesne başka bir nesnenin prototipine dayanarak özellik ve metotlar alabilir. JavaScript’te her nesne, bir prototip (üst nesne) referansına sahiptir. Eğer bir nesne, kendi içinde aranan bir özelliği veya metodu bulamazsa, bu özellik veya metod prototipe bakılarak aranır.
Prototypal inheritance, klasik sınıf tabanlı kalıtımdan farklıdır çünkü her nesne doğrudan başka bir nesneden türetilir, sınıflar arasındaki ilişkiler ise prototipler aracılığıyla kurulur.
JavaScript'te Prototipler ve proto Özelliği
JavaScript nesnelerinin her biri bir prototipe sahiptir. Bu prototipler, nesnenin oluşturulma şekline bağlı olarak farklılık gösterebilir. Bir nesne oluşturduğunda, onun prototipi o nesnenin "üst nesnesi" olarak kabul edilir.
proto Özelliği
Her JavaScript nesnesi, kendisinin prototipine ulaşmak için __proto__
özelliğine sahiptir. Bu özellik, bir nesnenin hangi prototipe ait olduğunu gösterir. Eğer nesne, prototipinde aranan bir özelliği bulamazsa, bu arama prototipin prototipine kadar devam eder. Bu işlem, JavaScript’in prototip zinciri olarak bilinir.
Prototip Zinciri (Prototype Chain)
Bir nesne, prototipine (üst nesnesine) bağlı olarak özellik ve metodlara erişebilir. Eğer nesnede aradığınız özellik ya da metod bulunmazsa, JavaScript otomatik olarak prototip zincirinde bir üst prototipe bakar. Bu zincir, son prototipe kadar devam eder.
Örneğin, aşağıdaki gibi bir nesne oluşturduğumuzda:
const insan = {
ad: 'Ahmet',
yas: 30,
selamla: function() {
console.log('Merhaba, benim adım ' + this.ad);
}
};
const ogrenci = Object.create(insan);
ogrenci.okul = 'Üniversite';
Burada, ogrenci
nesnesi insan
nesnesini prototip olarak alır. Bu durumda, ogrenci
nesnesi insan
nesnesinin selamla
metodunu ve ad
, yas
özelliklerini miras alır.
console.log(ogrenci.ad); // Ahmet
ogrenci.selamla(); // Merhaba, benim adım Ahmet
Bu örnekte, ogrenci
nesnesi insan
nesnesinin özelliklerini ve metodlarını devralmıştır. Ancak, ogrenci
nesnesinin kendisinde selamla
metodu tanımlanmadığı için, JavaScript bu metodu insan
nesnesinde arar.
Prototip Tabanlı Kalıtım ile Nesne Oluşturma
JavaScript’te yeni nesneler oluştururken, prototip tabanlı kalıtım kullanarak daha esnek bir yapı oluşturabilirsiniz. Bu genellikle Object.create()
yöntemi ile yapılır. Object.create()
metodu, yeni bir nesne oluşturur ve verilen prototipe dayalı olarak bu nesneyi oluşturur.
Object.create() Yöntemi ile Nesne Oluşturma
const person = {
introduce: function() {
console.log(`Merhaba, benim adım ${this.name}`);
}
};
const ali = Object.create(person);
ali.name = 'Ali';
ali.introduce(); // Merhaba, benim adım Ali
Bu örnekte, ali
nesnesi person
nesnesinin prototipi ile oluşturulmuştur. Sonrasında ali
nesnesine yeni bir özellik (name
) eklenmiş ve introduce
metodunu çağırarak, prototip tabanlı kalıtımı kullanarak işlevsellik eklenmiştir.
Prototypal Inheritance ile Klasik Nesne Yönelimli Programlamaya Benzer Yapılar Kurmak
JavaScript, prototip tabanlı kalıtım sunan bir dil olmasına rağmen, modern JavaScript (ES6 ve sonrası) ile class yapısı da eklenmiştir. Ancak, yine de class
yapıları, arka planda prototip tabanlı kalıtım kullanmaktadır.
Prototip ve Constructor Fonksiyonları
JavaScript’te bir nesne fonksiyonu tanımlayarak prototip tabanlı kalıtımı kullanabilirsiniz. Bir constructor fonksiyonu, bir nesne yaratmak için kullanılır ve bu nesne otomatik olarak prototip zincirine bağlanır.
function Animal(ad) {
this.ad = ad;
}
Animal.prototype.tanistir = function() {
console.log(`Merhaba, benim adım ${this.ad}`);
};
const kedi = new Animal('Kara');
kedi.tanistir(); // Merhaba, benim adım Kara
Burada, Animal
adlı constructor fonksiyonu bir nesne oluşturuyor ve tanistir
metodu, Animal
fonksiyonunun prototipine ekleniyor. kedi
nesnesi bu metodu devralıyor.
ES6 Class ile Prototip Tabanlı Kalıtım
ES6 ile birlikte JavaScript, prototip tabanlı kalıtımı daha klasik nesne yönelimli dillerde olduğu gibi sınıflar ile gerçekleştirmeye imkan tanır. Ancak burada da temelde hala prototipler kullanılır.
class Animal {
constructor(ad) {
this.ad = ad;
}
tanistir() {
console.log(`Merhaba, benim adım ${this.ad}`);
}
}
const kedi = new Animal('Kara');
kedi.tanistir(); // Merhaba, benim adım Kara
Yukarıdaki örnekte, class
yapısı kullanılarak Animal
nesnesi oluşturulmuş ve tanistir
metodu Animal
sınıfının prototipine eklenmiştir. Ancak, her iki örnekte de prototip tabanlı kalıtım kullanıldığı gerçeği değişmemektedir.
Prototypal Inheritance’ın Avantajları
- Daha Esnek: Prototip tabanlı kalıtım, JavaScript’te daha esnek bir yapı sağlar. Çünkü her nesne, başka bir nesne üzerinden miras alabilir, bu da esnek ve dinamik bir yapı kurmanıza olanak tanır.
- Dinamik Davranışlar: JavaScript prototipleri, çalışma zamanında nesnelere metot eklemeyi mümkün kılar. Bu, özellikle uygulamanın çalışma esnasında dinamik olarak fonksiyonellik eklemek için oldukça kullanışlıdır.
- Daha Az Hafıza Tüketimi: Prototip tabanlı kalıtım, metotları her nesne için yeniden tanımlamak yerine, sadece bir kez prototip üzerinde tanımlanmasına olanak tanır. Bu da bellek tasarrufu sağlar.
Sonuç
JavaScript’te Prototypal Inheritance, nesne tabanlı programlamanın temel taşlarından biridir. Nesnelerin, diğer nesnelerden özellik ve metot devralmasını sağlayan bu mekanizma, dilin esnekliğini artırır. Prototip tabanlı kalıtım, klasik sınıf tabanlı kalıtım anlayışından farklı olsa da, nesneler arasındaki ilişkiyi kurmanın etkili bir yoludur.
Prototip tabanlı kalıtımı anlamak ve doğru kullanmak, JavaScript’in derinliklerine inmek isteyen her geliştirici için önemli bir adımdır. Modern JavaScript’te kullanılan class
yapısı bile, arka planda prototip tabanlı kalıtımı kullanır ve bu mekanizmanın temellerini anlamak, daha etkili ve verimli kod yazmanızı sağlar.
Yorum Yap