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

# call, apply ve bind

Bağlamı çağrı yerinde belirleyen üç işlem, argüman aktarma biçimleri, fonksiyon ödünç alma kalıbı, kısmi uygulama ve kalıcı bağın kimlik maliyeti.

Önceki ders açık bağlanmayı bir kural olarak tanıttı ve şunu gösterdi: prototip zinciri
fonksiyonun nerede bulunacağını, `this` hangi veri üzerinde çalışacağını belirler. İkisi
bağımsız olduğu için, bir nesne hiç tanımadığı bir yöntemle çalıştırılabilir.

Bu bağımsızlığı kullanan üç işlem vardır. `call` ve `apply` bağlamı yalnızca o çağrı için
belirler ve fonksiyonu hemen çalıştırır; `bind` ise bağı kalıcı biçimde taşıyan **yeni bir
fonksiyon** üretir. Ders üçünün farklarını, ödünç alma kalıbını ve kalıcı bağın bedelini
ele alır.

## Argümanların Aktarılması

`call` ile `apply` arasındaki tek fark argümanların nasıl verildiğidir: `call` onları tek
tek alır, `apply` bir dizi olarak.

```js
const olcumDavranisi = {
  ozetle(onEk, ayrac) {
    return `${onEk}${ayrac}${this.sensor}${ayrac}${this.deger}`;
  },
};

const kayit = { sensor: "S-01", deger: 21.4 };
const argumanlar = ["olcum", " | "];

console.log(olcumDavranisi.ozetle.call(kayit, "olcum", " | "));
console.log(olcumDavranisi.ozetle.apply(kayit, argumanlar));
console.log(olcumDavranisi.ozetle.call(kayit, ...argumanlar));

const degerler = [21.4, 19.8, 25.1, 18.2];
console.log(Math.max.apply(null, degerler));
console.log(Math.max(...degerler));

try {
  olcumDavranisi.ozetle.call(null, "olcum", "-");
} catch (hata) {
  console.log(`null baglam: ${hata.constructor.name}`);
}
```

```
olcum | S-01 | 21.4
olcum | S-01 | 21.4
olcum | S-01 | 21.4
25.1
25.1
null baglam: TypeError
```

Yayma işleci dile girdikten sonra `apply` işleminin argüman açma işlevi büyük ölçüde
gereksizleşmiştir; üçüncü ve beşinci satırlar aynı işi yayma ile yapar. `apply`, argüman
listesi çalışma zamanında hesaplanan ve dizi olarak elde tutulan durumlarda hâlâ
doğrudan bir yol sunar.

Son satır bir ayrıntıyı sabitler: katı kipte `null` ya da `undefined` bağlamı genel nesneye
çevrilmez, olduğu gibi aktarılır. Bu yüzden `Math.max.apply(null, ...)` çalışır — `Math.max`
`this` değerini hiç kullanmaz — ama `this` okuyan bir fonksiyon aynı çağrıda hata verir.

## Fonksiyon Ödünç Alma

Açık bağlanmanın asıl kullanımı **fonksiyon ödünç alma (function borrowing)**: bir
nesnenin zincirinde bulunmayan bir yöntemi, o nesne üzerinde çalıştırmak.

```js
const diziBenzeri = { 0: "S-01", 1: "S-02", 2: "S-03", length: 3 };

console.log(Array.prototype.join.call(diziBenzeri, ";"));
console.log(Array.prototype.map.call(diziBenzeri, (a) => a.toLowerCase()).join(","));
console.log(Array.from(diziBenzeri).join(","));
console.log(Array.isArray(diziBenzeri));

const sozluk = Object.create(null);
sozluk.sensor = "S-01";

console.log(typeof sozluk.hasOwnProperty);
console.log(Object.prototype.hasOwnProperty.call(sozluk, "sensor"));
console.log(Object.hasOwn(sozluk, "sensor"));

console.log(Object.prototype.toString.call([1, 2]));
console.log(Object.prototype.toString.call(null));
console.log(Object.prototype.toString.call(new Date(0)));
console.log(Object.prototype.toString.call({ sensor: "S-01" }));
```

```
S-01;S-02;S-03
s-01,s-02,s-03
S-01,S-02,S-03
false
undefined
true
true
[object Array]
[object Null]
[object Date]
[object Object]
```

İlk üç satır **dizi benzeri (array-like)** nesneleri gösterir: sayısal anahtarlar ve bir
`length` özelliği taşıyan, ama zincirinde `Array.prototype` bulunmayan nesneler. Dizi
yöntemleri yalnızca bu iki şeye baktığı için ödünç alınabilirler. Dördüncü satır nesnenin
gerçekten dizi olmadığını doğrular. `Array.from` aynı işi daha okunur biçimde yapar ve
ödünç almaya çoğu durumda tercih edilir.

Beşinci ve altıncı satırlar ilk dersteki prototipsiz sözlüğe bağlanır. Böyle bir nesnede
`hasOwnProperty` yoktur, çünkü zinciri yoktur; sorgu ancak `Object.prototype` üzerinden
ödünç alınarak yapılabilir. `Object.hasOwn` bu ödünç almanın dile eklenmiş biçimidir ve
aynı sonucu daha az dolayımla verir.

Son dört satır, `Object.prototype.toString` yönteminin her değer türü için ayırt edici bir
etiket üretmesinden yararlanır. `typeof` işlecinin ayıramadığı durumları — dizi ile nesne,
`null` ile nesne — bu ödünç alma ayırır.

## Kalıcı Bağ ve Kısmi Uygulama

`bind`, fonksiyonu çalıştırmaz; bağlamı ve isteğe bağlı olarak baştaki argümanları
sabitlenmiş **yeni bir fonksiyon** döndürür. Argümanların önden sabitlenmesine **kısmi
uygulama (partial application)** denir.

```js
function kalibreEt(kayma, carpan, hamDeger) {
  return (hamDeger + kayma) * carpan;
}

const sensorS01 = kalibreEt.bind(null, -0.4, 1.02);

console.log(kalibreEt(-0.4, 1.02, 21.4).toFixed(3));
console.log(sensorS01(21.4).toFixed(3));
console.log(sensorS01(19.8).toFixed(3));

console.log(kalibreEt.length);
console.log(sensorS01.length);
console.log(sensorS01.name);

const kayit = {
  sensor: "S-01",
  deger: 21.4,
  bicimle() {
    return `${this.sensor}: ${this.deger}`;
  },
};

const bagliBicimle = kayit.bicimle.bind(kayit);
const yeniden = bagliBicimle.bind({ sensor: "S-99", deger: 0 });

console.log(bagliBicimle());
console.log(yeniden());
```

```
21.420
21.420
19.788
3
1
bound kalibreEt
S-01: 21.4
S-01: 21.4
```

Kısmi uygulama, her sensör için ayrı bir kalibrasyon fonksiyonu üretmenin doğrudan yoludur;
sabit parametreler bir kez verilir, değişen parametre her çağrıda. Fonksiyonun `length`
özelliği sabitlenen argüman sayısı kadar azalır, `name` özelliği ise türetilmiş olduğunu
belirtir.

Son iki satır kritik bir kuralı gösterir: **bağlı fonksiyon yeniden bağlanamaz.** İkinci
`bind` çağrısı yeni bir fonksiyon üretir ama içteki bağ değişmez, bu yüzden sonuç
değişmemiştir. Aynı kural önceki dersteki öncelik sırasının bir parçasıydı; `new` bu
kuralın tek istisnasıdır.

Kayan noktalı çıktıların `toFixed` ile biçimlendirilmesi bilinçlidir: `(21.4 - 0.4) * 1.02`
ifadesinin doğrudan yazdırılması, ikilik kesir gösteriminden gelen basamakları da
gösterirdi. Bilgisayarlar Nasıl Çalışır kursundaki Kayan Noktalı Sayılar dersi bu davranışı
açıklar.

## Geri Çağrılarda Bağı Korumak

Önceki dersteki kopma sorununun en sık görüldüğü yer, yöntemin bir geri çağrı olarak
aktarılmasıdır. Üç çözüm vardır ve üçü de aynı sonucu verir.

```js
class OlcumToplayici {
  constructor(sensor) {
    this.sensor = sensor;
    this.degerler = [];
  }
  ekle(deger) {
    this.degerler.push(deger);
  }
  ozet() {
    return `${this.sensor}: ${this.degerler.join(",")}`;
  }
}

const toplayici = new OlcumToplayici("S-01");
const gelenler = [21.4, 19.8, 25.1];

try {
  gelenler.forEach(toplayici.ekle);
} catch (hata) {
  console.log(`baglamsiz: ${hata.constructor.name}`);
}

gelenler.forEach(toplayici.ekle.bind(toplayici));
console.log(toplayici.ozet());

const ikinci = new OlcumToplayici("S-02");
gelenler.forEach(ikinci.ekle, ikinci);
console.log(ikinci.ozet());

const ucuncu = new OlcumToplayici("S-03");
gelenler.forEach((deger) => ucuncu.ekle(deger));
console.log(ucuncu.ozet());
```

```
baglamsiz: TypeError
S-01: 21.4,19.8,25.1
S-02: 21.4,19.8,25.1
S-03: 21.4,19.8,25.1
```

Birinci çözüm `bind` ile kalıcı bağ üretir. İkincisi, `forEach` gibi bazı dizi
yöntemlerinin ikinci parametre olarak aldığı bağlam argümanını kullanır — bu seçenek
`map`, `filter`, `some` ve `every` yöntemlerinde de bulunur, ama her yüksek mertebeden
fonksiyonda bulunmaz. Üçüncüsü çağrıyı bir ok fonksiyonuyla sarar ve bağlanmayı hiç
gerektirmez; nedeni sonraki dersin konusudur.

## Bağın Kimlik Maliyeti

`bind` her çağrıldığında yeni bir fonksiyon nesnesi üretir. Bu, kimlik karşılaştırmasına
dayanan her yerde sonuç doğurur.

```js
const kayit = {
  sensor: "S-01",
  bicimle() {
    return `kayit: ${this.sensor}`;
  },
};

const birinci = kayit.bicimle.bind(kayit);
const ikinci = kayit.bicimle.bind(kayit);

console.log(birinci() === ikinci());
console.log(birinci === ikinci);
console.log(birinci === kayit.bicimle);

class Dinleyici {
  constructor(ad) {
    this.ad = ad;
    this.isle = this.isle.bind(this);
  }
  isle(olay) {
    return `${this.ad} <- ${olay}`;
  }
}

const a = new Dinleyici("A");
const b = new Dinleyici("B");

console.log(a.isle("olcum"));
console.log(Object.hasOwn(a, "isle"));
console.log(a.isle === b.isle);
console.log(Dinleyici.prototype.isle === Object.getPrototypeOf(a).isle);
console.log(a.isle === Dinleyici.prototype.isle);
```

```
true
false
false
A <- olcum
true
false
true
false
```

İki `bind` çağrısı aynı sonucu üreten ama birbirine eşit olmayan iki fonksiyon verir. Bir
olay dinleyicisini kaydettikten sonra kaldırmak için aynı fonksiyon başvurusu gerektiğinden,
`bind` sonucunun saklanması zorunludur; her seferinde yeniden bağlanan bir fonksiyon
kaldırılamaz.

İkinci bölüm, sınıf yapıcısında yapılan bağlamanın prototip modeline etkisini gösterir.
`this.isle = this.isle.bind(this)` satırı, prototipteki yöntemi gölgeleyen bir **kendi
özellik** yaratır. Sonuç: her örnek kendi bağlı fonksiyonunu taşır, örnekler arasındaki
paylaşım kaybolur, bellekteki fonksiyon sayısı örnek sayısıyla artar. Prototipteki asıl
tanım yerinde durur ama artık kullanılmaz.

Bu, kursun ilk dersindeki ödünleşimin geri dönüşüdür: paylaşılan davranış zincirde
durduğunda ucuzdur, örneğe kopyalandığında pahalı ama bağlamı garantilidir. Kapanışlar
dersi bu ödünleşimi tekrar ve daha genel biçimde ele alacaktır.

## Özet

- `call` ve `apply` bağlamı yalnızca o çağrı için belirler; fark yalnızca argümanların tek
  tek mi dizi olarak mı verildiğidir.
- Katı kipte `null` ve `undefined` bağlamı genel nesneye çevrilmez.
- Fonksiyon ödünç alma, bir yöntemi zincirinde bulunmadığı bir nesne üzerinde çalıştırır;
  dizi benzeri nesneler ve prototipsiz sözlükler bunun tipik durumlarıdır.
- `bind` yeni bir fonksiyon üretir, argümanları kısmen sabitleyebilir ve ürettiği bağ
  yeniden bağlamayla değiştirilemez.
- Her `bind` çağrısı yeni bir kimlik üretir; kaldırılabilir dinleyicilerde sonucun
  saklanması gerekir.
- Yapıcıda yapılan bağlama, prototipteki yöntemi örnek başına bir kopyayla gölgeler ve
  paylaşımı ortadan kaldırır.

## Sonraki Adım

Önceki bölümde geri çağrı sorununun üçüncü çözümü bir ok fonksiyonuydu ve hiçbir bağlama
işlemi gerektirmedi. Bunun nedeni, ok fonksiyonlarının `this` değerini çağrı yerinden
almamasıdır — kendilerine ait bir bağlamları yoktur. Sonraki ders bu davranışı, sağladığı
kolaylığı ve ok fonksiyonunun yöntem olarak kullanılamadığı durumları inceleyecek.
