---
title: 'Prototipsel Kalıtım'
source: 'https://academia.sh/tr/kurslar/javascript-nesne-modeli/prototipsel-kalitim'
course: "JavaScript'te Nesneler ve Fonksiyonlar"
language: tr
updated: '2026-08-17T18:09:50+00:00'
license: 'CC BY-SA 4.0'
---

# Prototipsel Kalıtım

Yapıcı işlevler ve new işlecinin kurduğu bağ, prototip zincirini iki katmana çıkarmak, tür sorgulama işlemleri ve bağın çalışma zamanında değişmesi.

Önceki ders prototip bağını elle kurdu: ortak davranış bir nesnede toplandı, her kayıt
`Object.create` ile ona bağlandı, alanlar tek tek dolduruldu. Kalıp işler ama iki
eksiği vardır. Alanların doldurulması ile davranışın bağlanması ayrı yerlerde durur, ve
bir kayıt türünden başka bir kayıt türü türetmenin yerleşik bir düzeni yoktur.

Dil, her ikisi için de yerleşik bir yol sunar. Bu ders o yolu — yapıcı işlev ve `new`
işlecini — açar, sonra `new` işlecinin yaptığı işi elle yazarak bunun bir sihir değil,
önceki derste gördüğünüz üç adımın kısaltması olduğunu gösterir.

## Yapıcı İşlev

JavaScript'te her fonksiyon, `prototype` adlı sıradan bir özellik taşır. Bu özellik
fonksiyonun kendi prototipi **değildir**; `new` ile çağrıldığında üreteceği nesnelerin
prototipi olacak nesnedir. Ad benzerliği bu ayrımı gizlediği için, iki kavramı
karıştırmamak gerekir.

`new` ile çağrılmak üzere yazılan fonksiyona **yapıcı işlev (constructor function)**
denir. Alanları `this` üzerinden doldurur, davranışları ise `prototype` nesnesine
yazılır.

```js
function OlcumKaydi(sensor, deger, zaman) {
  this.sensor = sensor;
  this.deger = deger;
  this.zaman = zaman;
}

OlcumKaydi.prototype.bicimle = function () {
  return `${this.sensor}@${this.zaman}: ${this.deger}`;
};

OlcumKaydi.prototype.esikAstiMi = function (esik) {
  return this.deger > esik;
};

const kayitBir = new OlcumKaydi("S-01", 21.4, 1000);
const kayitIki = new OlcumKaydi("S-02", 19.8, 1060);

console.log(kayitBir.bicimle());
console.log(Object.getPrototypeOf(kayitBir) === OlcumKaydi.prototype);
console.log(kayitBir.bicimle === kayitIki.bicimle);
console.log(Object.keys(kayitBir).join(","));
console.log(kayitBir.constructor === OlcumKaydi);
console.log(Object.hasOwn(OlcumKaydi.prototype, "constructor"));
```

```
S-01@1000: 21.4
true
true
sensor,deger,zaman
true
true
```

Sonuç önceki dersteki kuruluşla aynıdır: veri her kayıtta ayrı, davranış tek yerde.
Dördüncü satır bunu doğrular — kaydın kendi özellikleri yalnızca üç veri alanıdır.

Beşinci ve altıncı satırlar bir ayrıntıyı açığa çıkarır. Her fonksiyonun `prototype`
nesnesi, yaratıldığı anda `constructor` adlı bir özellik taşır ve bu özellik fonksiyonun
kendisini gösterir. `kayitBir.constructor` ifadesi kayıtta bulunmaz; zincirden,
`OlcumKaydi.prototype` üzerinden gelir. Yani `constructor` bir nesnenin "gerçek türü"
değil, zincirinde rastlanan sıradan bir özelliktir — sonraki bölümde bu ayrımın bedeli
görülecektir.

## new İşlecinin Yaptığı İş

`new OlcumKaydi(...)` ifadesi dört adıma ayrılır:

1. Prototipi `OlcumKaydi.prototype` olan boş bir nesne yaratılır.
2. Yapıcı işlev, `this` bu nesneye bağlanmış olarak çağrılır.
3. Yapıcı işlev bir nesne döndürüyorsa o nesne, döndürmüyorsa ilk adımdaki nesne
   sonuç olur.
4. Sonuç ifadenin değeri olur.

Bu adımların hepsi sıradan işlemlerdir; hiçbirinde dile özel bir yetki yoktur. Aynı işi
yapan bir fonksiyon yazılabilir.

```js
function OlcumKaydi(sensor, deger, zaman) {
  this.sensor = sensor;
  this.deger = deger;
  this.zaman = zaman;
}
OlcumKaydi.prototype.bicimle = function () {
  return `${this.sensor}@${this.zaman}: ${this.deger}`;
};

function yeniOrnek(YapiciIslev, ...argumanlar) {
  const nesne = Object.create(YapiciIslev.prototype);
  const sonuc = YapiciIslev.apply(nesne, argumanlar);
  return typeof sonuc === "object" && sonuc !== null ? sonuc : nesne;
}

const elle = yeniOrnek(OlcumKaydi, "S-01", 21.4, 1000);
const islecle = new OlcumKaydi("S-01", 21.4, 1000);

console.log(elle.bicimle());
console.log(Object.getPrototypeOf(elle) === OlcumKaydi.prototype);
console.log(JSON.stringify(elle) === JSON.stringify(islecle));
console.log(elle instanceof OlcumKaydi);
```

```
S-01@1000: 21.4
true
true
true
```

`yeniOrnek` işlevi `new` işlecinin yerine geçer ve ayırt edilemeyen bir sonuç üretir.
`apply` çağrısı `this` bağlamasını açıkça kurar; bu işlemin kuralları Bağlam ve
Kapanışlar konusunun ilk iki dersinde ele alınacaktır. Buradaki asıl gözlem şudur:
`new`, prototip modelinin üzerine konmuş bir kısaltmadır, ayrı bir mekanizma değil.

Yazdığımız `yeniOrnek` işlevi `new` işlecinin tamamını karşılamaz; sınıf sözdizimiyle
tanımlanmış yapıcılar `new` olmadan çağrılamaz ve `new.target` gibi ayrıntılar bu
kısaltmanın dışında kalır. Model açısından fark eden kısım yukarıdaki üç satırdır.

## Zinciri Uzatmak

Ölçüm kayıtlarının bir alt türünü ele alalım: sensörün sistematik sapmasını taşıyan
**kalibreli ölçüm**. Alanları ölçüm kaydının alanlarını kapsar, üzerine bir kayma değeri
ekler; okunan değeri hesaplama biçimi farklıdır, biçimlendirme biçimi aynıdır.

Zinciri iki katmana çıkarmak için iki iş gerekir: alt türün prototipi üst türün
prototipine bağlanmalı, ve alt yapıcı çalışırken üst yapıcının alan doldurma işi de
yapılmalıdır.

```js
function OlcumKaydi(sensor, deger, zaman) {
  this.sensor = sensor;
  this.deger = deger;
  this.zaman = zaman;
}
OlcumKaydi.prototype.bicimle = function () {
  return `${this.sensor}@${this.zaman}: ${this.deger}`;
};
OlcumKaydi.prototype.okunanDeger = function () {
  return this.deger;
};

function KalibreliOlcum(sensor, deger, zaman, kayma) {
  OlcumKaydi.call(this, sensor, deger, zaman);
  this.kayma = kayma;
}

KalibreliOlcum.prototype = Object.create(OlcumKaydi.prototype);
KalibreliOlcum.prototype.constructor = KalibreliOlcum;

KalibreliOlcum.prototype.okunanDeger = function () {
  return this.deger + this.kayma;
};

const kalibreli = new KalibreliOlcum("S-03", 21.4, 1120, -0.4);

console.log(kalibreli.bicimle());
console.log(kalibreli.okunanDeger());
console.log(OlcumKaydi.prototype.okunanDeger.call(kalibreli));
console.log(Object.getPrototypeOf(kalibreli) === KalibreliOlcum.prototype);
console.log(Object.getPrototypeOf(KalibreliOlcum.prototype) === OlcumKaydi.prototype);
console.log(kalibreli.constructor === KalibreliOlcum);
```

```
S-03@1120: 21.4
21
21.4
true
true
true
```

Zincir dört halkaya çıktı: `kalibreli` → `KalibreliOlcum.prototype` →
`OlcumKaydi.prototype` → `Object.prototype` → `null`. `bicimle` ikinci halkada
bulunmaz, üçüncüde bulunur; `okunanDeger` ikinci halkada bulunduğu için üçüncüdeki
tanımı gölgeler. Programlama Temelleri kursundaki Nesneye Dayalı Programlamaya Giriş
dersinde tanıtılan **çok biçimlilik**, burada tam olarak bu gölgelemedir: aynı ad, zincirin
farklı katmanlarında farklı gerçekleştirimlere karşılık gelir ve hangisinin çalışacağına
arama sırası karar verir.

Üç satır dikkat ister. `OlcumKaydi.call(this, ...)` üst yapıcının alan doldurma işini
yeni nesne üzerinde çalıştırır. `Object.create(OlcumKaydi.prototype)` ile kurulan bağ,
`KalibreliOlcum.prototype = OlcumKaydi.prototype` biçiminde kurulsaydı iki tür aynı
prototip nesnesini paylaşırdı ve alt türe eklenen her davranış üst türe de sızardı.
`constructor` özelliğinin elle geri yazılması ise ilk bölümdeki gözlemin sonucudur:
`prototype` nesnesi değiştirildiğinde `constructor` ile birlikte kaybolur, yeniden
yazılmazsa `kalibreli.constructor` zincirden `OlcumKaydi` değerini bulur.

## Zincirde Tür Sorgulama

`instanceof` işleci, sağındaki fonksiyonun `prototype` nesnesinin, solundaki nesnenin
zincirinde bulunup bulunmadığını sorar. Sınıf üyeliği gibi görünen bu sorgu, aslında bir
zincir taramasıdır.

```js
function OlcumKaydi(sensor, deger) {
  this.sensor = sensor;
  this.deger = deger;
}
function KalibreliOlcum(sensor, deger, kayma) {
  OlcumKaydi.call(this, sensor, deger);
  this.kayma = kayma;
}
KalibreliOlcum.prototype = Object.create(OlcumKaydi.prototype);
KalibreliOlcum.prototype.constructor = KalibreliOlcum;

const kalibreli = new KalibreliOlcum("S-03", 21.4, -0.4);
const yalin = new OlcumKaydi("S-01", 21.4);

console.log(kalibreli instanceof KalibreliOlcum);
console.log(kalibreli instanceof OlcumKaydi);
console.log(kalibreli instanceof Object);
console.log(yalin instanceof KalibreliOlcum);

console.log(OlcumKaydi.prototype.isPrototypeOf(kalibreli));
console.log(KalibreliOlcum.prototype.isPrototypeOf(yalin));

let durak = kalibreli;
const zincir = [];
while (durak !== null) {
  durak = Object.getPrototypeOf(durak);
  zincir.push(durak === null ? "null" : durak.constructor.name);
}
console.log(zincir.join(" -> "));
```

```
true
true
true
false
true
false
KalibreliOlcum -> OlcumKaydi -> Object -> null
```

Son blok zinciri baştan sona yürüyerek yazdırır ve `instanceof` sonuçlarının nereden
geldiğini görünür kılar. Kalibreli ölçümün zincirinde her üç `prototype` nesnesi de
bulunduğu için üç sorgu da olumlu yanıtlanır; yalın kayıt alt türün prototipini
zincirinde taşımadığı için dördüncü sorgu olumsuzdur. `isPrototypeOf` aynı soruyu ters
yönden sorar ve fonksiyona değil doğrudan prototip nesnesine bakar.

## Bağın Canlılığı

Prototip bağı bir kopya değil, canlı bir başvurudur. Nesne yaratıldıktan sonra prototipe
eklenen bir özellik, var olan tüm nesnelerde hemen görünür.

```js
function OlcumKaydi(sensor, deger) {
  this.sensor = sensor;
  this.deger = deger;
}
OlcumKaydi.prototype.bicimle = function () {
  return `${this.sensor}: ${this.deger}`;
};

const kayit = new OlcumKaydi("S-01", 21.4);
console.log(kayit.bicimle());
console.log(typeof kayit.ozetle);

OlcumKaydi.prototype.ozetle = function () {
  return `${this.sensor} kaydi`;
};

console.log(typeof kayit.ozetle);
console.log(kayit.ozetle());

const digerDavranis = {
  bicimle() {
    return `[${this.sensor}] ${this.deger}`;
  },
};
Object.setPrototypeOf(kayit, digerDavranis);
console.log(kayit.bicimle());
console.log(kayit instanceof OlcumKaydi);
console.log(typeof kayit.ozetle);
```

```
S-01: 21.4
undefined
function
S-01 kaydi
[S-01] 21.4
false
undefined
```

`ozetle` kaydın yaratılmasından sonra eklenmiştir ve hiçbir yeniden yaratma olmadan
erişilebilir olur; arama her okumada baştan yapıldığı için bağ canlıdır.

`Object.setPrototypeOf` var olan bir nesnenin bağını değiştirir. Sonuçlar geniştir:
kayıt artık üst türün davranışlarını görmez, `instanceof` sonucu tersine döner, ve
çalışma zamanları nesne biçimlerine göre eniyileme yaptığı için erişim başarımı düşer.
Bu nedenle bağ, nesnenin yaratıldığı anda kurulur ve sonradan değiştirilmez;
`Object.create` ya da `new` bunun için vardır.

## Özet

- Her fonksiyonun `prototype` özelliği, `new` ile üreteceği nesnelerin prototipi olacak
  nesnedir; fonksiyonun kendi prototipi değildir.
- `new`, prototipi `prototype` nesnesine bağlı boş bir nesne yaratır, yapıcıyı bu nesne
  üzerinde çalıştırır ve sonucu döndürür; aynı iş `Object.create` ile elle yazılabilir.
- Zinciri uzatmak iki işten oluşur: alt prototipi üst prototipe bağlamak ve üst yapıcıyı
  alt yapıcı içinden çağırmak.
- Alt katmandaki aynı adlı tanım üsttekini gölgeler; çok biçimlilik bu arama sırasının
  sonucudur.
- `instanceof` ve `isPrototypeOf`, tür üyeliğini değil, bir prototip nesnesinin zincirde
  bulunup bulunmadığını sorar.
- Bağ canlıdır: prototipe sonradan eklenen özellikler var olan nesnelerde görünür.

## Sonraki Adım

Bu derste zincir elle kuruldu ve kuruluşun her adımı görünür oldu: `prototype` ataması,
`constructor` onarımı, üst yapıcı çağrısı. Üç adımın da unutulmaya açık olması, dile
bunları tek bir bildirimde toplayan bir sözdizim eklenmesinin gerekçesidir. Sonraki ders
sınıf sözdizimini tanıtacak ve her satırının bu derste elle yazdığınız hangi işleme
karşılık geldiğini, aynı sınamalarla gösterecek.
