---
title: 'Nesne Prototipi'
source: 'https://academia.sh/tr/kurslar/javascript-nesne-modeli/nesne-prototipi'
course: "JavaScript'te Nesneler ve Fonksiyonlar"
language: tr
updated: '2026-08-17T18:09:50+00:00'
license: 'CC BY-SA 4.0'
---

# Nesne Prototipi

Her nesnenin taşıdığı prototip bağı, özelliklerin bu bağ üzerinden aranma sırası, kendi özellik ile devralınan özellik ayrımı ve zincirin sonu.

JavaScript Temelleri kursu nesneyi anahtar–değer eşlemesi olarak tanıttı: özellik yazılır,
okunur, silinir. Bu tanım günlük kullanım için yeterlidir ama bir soruyu yanıtsız bırakır.
Boş bir nesne yaratıp `toString` özelliğini okuduğunuzda tanımsız değil, bir fonksiyon
elde edersiniz. O fonksiyonu oraya kimse yazmadı.

Yanıt, dilin nesne modelinin merkezinde durur: her nesne, kendi özelliklerine ek olarak
**başka bir nesneye bir bağ** taşır. Aradığınız özellik nesnenin kendisinde yoksa, arama
bu bağ üzerinden devam eder. Bu ders o bağı kurar; kursun geri kalanı — sınıf sözdizimi de
dahil — onun üzerine oturur.

## Aynı Davranışın İki Kopyası

Kurs boyunca tek bir somut örnek üzerinde çalışacağız: bir sensörden okunan **ölçüm
kaydı**. Kayıt üç veri taşır (sensör kimliği, ölçülen değer, ölçüm anı) ve en az bir
davranış sunar (kendini okunabilir biçimde yazdırmak). En doğrudan kuruluş, her kaydı
kendi başına bir nesne değişmezi olarak yazmaktır.

```js
const kayitBir = {
  sensor: "S-01",
  deger: 21.4,
  zaman: 1000,
  bicimle() {
    return `${this.sensor}@${this.zaman}: ${this.deger}`;
  },
};

const kayitIki = {
  sensor: "S-02",
  deger: 19.8,
  zaman: 1060,
  bicimle() {
    return `${this.sensor}@${this.zaman}: ${this.deger}`;
  },
};

console.log(kayitBir.bicimle());
console.log(kayitIki.bicimle());
console.log(kayitBir.bicimle === kayitIki.bicimle);
```

```
S-01@1000: 21.4
S-02@1060: 19.8
false
```

Son satır sorunu görünür kılar. İki kayıt aynı davranışı sunar, ama bellekte **iki ayrı
fonksiyon nesnesi** vardır; kimlik karşılaştırması bunu söyler. Bin ölçüm için bin
kopya oluşur ve biçimlendirme kuralı değiştiğinde bin yerde değişmesi gerekir.

Programlama Temelleri kursundaki Nesneye Dayalı Programlamaya Giriş dersi bu soruna sınıf
kavramıyla yanıt vermişti: davranış sınıfta bir kez yazılır, nesneler onu paylaşır.
JavaScript'in yanıtı bir adım daha alttadır ve sınıf gerektirmez.

## Prototip Bağı

Her nesne, yaratıldığı anda başka bir nesneye — ya da `null` değerine — bağlanır. Bu
bağa **prototip (prototype)** denir. Bağ, nesnenin sıradan bir özelliği değildir; dilin
belirtiminde `[[Prototype]]` adlı iç bir alan olarak geçer ve `Object.getPrototypeOf`
işleviyle okunur.

`Object.create` bağı doğrudan kurar: verilen nesneyi prototip alan yeni bir nesne üretir.

```js
const olcumDavranisi = {
  bicimle() {
    return `${this.sensor}@${this.zaman}: ${this.deger}`;
  },
  esikAstiMi(esik) {
    return this.deger > esik;
  },
};

function olcumKaydi(sensor, deger, zaman) {
  const kayit = Object.create(olcumDavranisi);
  kayit.sensor = sensor;
  kayit.deger = deger;
  kayit.zaman = zaman;
  return kayit;
}

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

console.log(kayitBir.bicimle());
console.log(kayitIki.esikAstiMi(20));
console.log(kayitBir.bicimle === kayitIki.bicimle);
console.log(Object.getPrototypeOf(kayitBir) === olcumDavranisi);
```

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

Üçüncü satır artık `true` verir: iki kayıt aynı fonksiyon nesnesini kullanır, çünkü
fonksiyon kayıtlarda değil, ortak prototipte durur. Dördüncü satır bağın kendisini
sınar — nesne modeliyle ilgili her iddia bu ders boyunca bu biçimde, doğrudan
sınanabilir bir karşılaştırmayla gösterilecektir.

Veri her kayıtta ayrı, davranış tek yerde. Bu ayrım prototip modelinin tüm işlevidir:
**değişen kısım nesnede, değişmeyen kısım zincirde durur.**

## Özellik Arama Sırası

Bir özelliği okuduğunuzda çalışma zamanı şu sırayı izler:

1. Nesnenin kendi özellikleri arasında ara. Bulunursa değeri döndür.
2. Bulunamazsa prototipine geç, aynı aramayı orada yap.
3. Zincir `null` değerine ulaşana kadar sürdür. Hiçbir yerde bulunmazsa `undefined` döndür.

Arama ilk bulduğunda durduğu için, nesnenin kendi özelliği aynı adlı prototip özelliğini
**gölgeler (shadowing)**. Programlama Temelleri kursundaki Kapsam ve Yaşam Süresi dersinde
iç kapsamın dış kapsamdaki adı gölgelemesi anlatılmıştı; buradaki mekanizma aynı fikrin
nesneler üzerindeki karşılığıdır.

```js
const olcumDavranisi = {
  bicimle() {
    return `${this.sensor}@${this.zaman}: ${this.deger}`;
  },
};

const kayit = Object.create(olcumDavranisi);
kayit.sensor = "S-01";
kayit.deger = 21.4;
kayit.zaman = 1000;

console.log(kayit.bicimle());

kayit.bicimle = function () {
  return `[ham] ${this.deger}`;
};

console.log(kayit.bicimle());
console.log(Object.hasOwn(kayit, "bicimle"));
console.log(olcumDavranisi.bicimle.call(kayit));

delete kayit.bicimle;
console.log(kayit.bicimle());
```

```
S-01@1000: 21.4
[ham] 21.4
true
S-01@1000: 21.4
S-01@1000: 21.4
```

Üç gözlem önemlidir. Birincisi, atama prototipteki fonksiyonu **değiştirmez**; kayda ait
yeni bir özellik yaratır. Yazma işlemi zincirde yukarı çıkmaz, her zaman nesnenin
kendisine yazar. İkincisi, gölgelenen özellik yok olmaz; `call` ile hâlâ çağrılabilir
(bu işlemin ayrıntısı Bağlam ve Kapanışlar konusundadır). Üçüncüsü, kendi özellik
silindiğinde zincir yeniden görünür olur — silme, prototipteki tanımı geri getiriyormuş
gibi görünür ama aslında yalnızca gölgeyi kaldırır.

## Kendi Özellik ve Devralınan Özellik

Zincir üzerinden gelen özellikler çoğu okuma işleminde kendi özelliklerden ayırt edilmez;
ayrımın önemli olduğu yerler ise sayma ve dizileştirme işlemleridir.

```js
const olcumDavranisi = {
  bicimle() {
    return `${this.sensor}@${this.zaman}: ${this.deger}`;
  },
};

const kayit = Object.create(olcumDavranisi);
kayit.sensor = "S-01";
kayit.deger = 21.4;
kayit.zaman = 1000;

console.log("bicimle" in kayit);
console.log(Object.hasOwn(kayit, "bicimle"));
console.log(Object.keys(kayit).join(","));

const forInAnahtarlari = [];
for (const anahtar in kayit) {
  forInAnahtarlari.push(anahtar);
}
console.log(forInAnahtarlari.join(","));

console.log(JSON.stringify(kayit));
```

```
true
false
sensor,deger,zaman
sensor,deger,zaman,bicimle
{"sensor":"S-01","deger":21.4,"zaman":1000}
```

`in` işleci zincirin tamamına bakar, `Object.hasOwn` yalnızca nesnenin kendisine.
`Object.keys` kendi özelliklerle sınırlıdır; `for...in` döngüsü ise zincirden gelen
özellikleri de dolaşır ve bu nedenle nesne üzerinde gezinmek için güvenilir bir araç
değildir. `JSON.stringify` de kendi özelliklerle çalışır — dizileştirme yalnızca veriyi
alır, davranışı bırakır. Bu davranış, dersin sonundaki ayrımı önceden haber verir:
**bir nesnenin verisi kendisinde, kimliği zincirindedir.**

Buradaki `bicimle` adının `for...in` çıktısında görünmesi, prototipteki özelliğin
*sayılabilir* olmasından kaynaklanır. Sayılabilirliğin nasıl denetlendiği Özellik
Tanımlayıcıları dersinin konusudur; sınıf sözdiziminin bu konudaki farkı da orada
gösterilecektir.

## Zincirin Sonu

Zincir sonsuz değildir. Nesne değişmeziyle yaratılan her nesnenin prototipi
`Object.prototype` nesnesidir ve onun prototipi `null` değeridir. `toString`,
`valueOf`, `hasOwnProperty` gibi adların her nesnede bulunmasının nedeni budur.

```js
const olcumDavranisi = {
  bicimle() {
    return `${this.sensor}@${this.zaman}: ${this.deger}`;
  },
};
const kayit = Object.create(olcumDavranisi);

console.log(Object.getPrototypeOf(kayit) === olcumDavranisi);
console.log(Object.getPrototypeOf(olcumDavranisi) === Object.prototype);
console.log(Object.getPrototypeOf(Object.prototype));

console.log(typeof kayit.toString);
console.log(typeof kayit.bilinmeyenOzellik);

const sozluk = Object.create(null);
sozluk.sensor = "S-01";
console.log(Object.getPrototypeOf(sozluk));
console.log(typeof sozluk.toString);
console.log("toString" in sozluk);
```

```
true
true
null
function
undefined
null
undefined
false
```

Zincir üç halkadan oluşur: `kayit` → `olcumDavranisi` → `Object.prototype` → `null`.
Var olmayan bir özellik istendiğinde çalışma zamanı bu üç durağı da gezer ve `undefined`
döndürür; hata vermez. Arama maliyeti zincir uzunluğuyla artar, ancak her durakta
yapılan iş bir sözlük aramasıdır — Veri Yapıları kursundaki Karma Tabloları dersinde
incelenen ortalama sabit maliyetli erişimin ta kendisi.

`Object.create(null)` ile üretilen nesnenin zinciri hiç yoktur. Böyle bir nesne saf
sözlük olarak davranır: `toString` gibi devralınan adlar bulunmadığı için, dışarıdan
gelen anahtarların yerleşik adlarla çakışma riski ortadan kalkar. Anahtarları program
dışından gelen eşlemelerde bu kuruluş, `for...in` ve `in` sonuçlarını da öngörülebilir
kılar. Aynı ihtiyacın dildeki asıl karşılığı `Map` türüdür ve İleri Koleksiyonlar
konusunda ele alınır.

## Özet

- Her nesne, kendi özelliklerine ek olarak bir prototip nesnesine bağ taşır; bağ
  `Object.getPrototypeOf` ile okunur ve doğrudan sınanabilir.
- Özellik araması nesnenin kendisinden başlar, bulunamazsa zincirde yukarı ilerler ve
  `null` durağında `undefined` ile sonuçlanır.
- Yazma işlemi zincire çıkmaz; her zaman nesnenin kendisine yazar ve aynı adlı prototip
  özelliğini gölgeler.
- `in` zincirin tamamına, `Object.hasOwn` ve `Object.keys` yalnızca kendi özelliklere
  bakar; `JSON.stringify` de kendi özelliklerle çalışır.
- Nesne değişmezleriyle kurulan zincir `Object.prototype` üzerinden `null` değerine
  ulaşır; `Object.create(null)` prototipsiz, saf sözlük davranışlı bir nesne üretir.

## Sonraki Adım

Bu derste prototip elle kuruldu: önce ortak davranış nesnesi yazıldı, sonra her kayıt
`Object.create` ile ona bağlandı. Bu kalıp çalışır ama bir tür tanımına benzemez — yeni
bir kayıt türü türetmek, ortak alanları doldurmak ve iki kayıt türü arasında ortak
davranışı paylaştırmak için tekrar eden bir düzen gerekir. Sonraki ders, nesneden nesneye
kalıtımın yerleşik kalıplarını inceleyecek ve `new` işlecinin bu bağı sizin yerinize nasıl
kurduğunu gösterecek.
