---
title: 'Yüksek Mertebeden Fonksiyonlar'
source: 'https://academia.sh/tr/kurslar/javascript-nesne-modeli/yuksek-mertebeden-fonksiyonlar'
course: "JavaScript'te Nesneler ve Fonksiyonlar"
language: tr
updated: '2026-08-17T18:09:50+00:00'
license: 'CC BY-SA 4.0'
---

# Yüksek Mertebeden Fonksiyonlar

Fonksiyonun değer olarak kullanılması, eşleme–süzme–indirgeme zinciri, karşılaştırıcı üreten fonksiyonlar, bileşim ve davranış ekleyen sarmalayıcılar.

Önceki dersler fonksiyonu sürekli değer gibi kullandı: geri çağrı olarak aktarıldı, bir
fabrikadan döndürüldü, nesneye özellik olarak yazıldı, `bind` ile yenisi üretildi.
Hepsinin dayanağı tek bir olgudur — JavaScript'te fonksiyon bir nesnedir; çağrılabilir
olması dışında sayı ya da dizgiden farkı yoktur.

Fonksiyonu argüman olarak alan ya da fonksiyon döndüren fonksiyonlara **yüksek mertebeden
fonksiyon (higher-order function)** denir. Programlama Temelleri kursundaki Fonksiyonel
Programlamaya Giriş dersi kavramı tanıtmıştı. Bu ders onu ölçüm kayıtları üzerinde
uygular ve önceki dersteki bağlanma kurallarının bu kullanımda nereye değdiğini gösterir.

## Fonksiyonu Argüman Olarak Vermek

En yaygın biçim, bir koleksiyon üzerindeki işlemin **ne yapacağını** dışarıdan almasıdır.
Süzme ölçütü, dönüştürme kuralı ve birikeç işlemi ayrı ayrı adlandırılmış fonksiyonlarda
tutulabilir.

```js
const kayitlar = [
  { sensor: "S-01", deger: 21.4, zaman: 1000 },
  { sensor: "S-02", deger: 19.8, zaman: 1060 },
  { sensor: "S-01", deger: 25.1, zaman: 1120 },
  { sensor: "S-03", deger: 18.2, zaman: 1180 },
  { sensor: "S-01", deger: 22.0, zaman: 1240 },
];

const esikUstunde = (kayit) => kayit.deger > 20;
const degeriAl = (kayit) => kayit.deger;
const topla = (birikec, deger) => birikec + deger;

const secilenler = kayitlar.filter(esikUstunde);
const degerler = secilenler.map(degeriAl);
const toplam = degerler.reduce(topla, 0);

console.log(secilenler.length);
console.log(degerler.join(","));
console.log(toplam.toFixed(1));
console.log((toplam / degerler.length).toFixed(3));

const sensoreGoreGrup = kayitlar.reduce((grup, kayit) => {
  (grup[kayit.sensor] ??= []).push(kayit.deger);
  return grup;
}, Object.create(null));

console.log(Object.keys(sensoreGoreGrup).join(","));
console.log(sensoreGoreGrup["S-01"].join(","));
console.log(typeof esikUstunde);
console.log(esikUstunde.length);
```

```
3
21.4,25.1,22
68.5
22.833
S-01,S-02,S-03
21.4,25.1,22
function
1
```

Süzme, eşleme ve indirgeme üç ayrı sorumluluğu ayırır: hangi kayıtların ilgilendiği, o
kayıtlardan hangi bilginin alındığı ve bilginin nasıl birleştirildiği. Her biri ayrı ayrı
sınanabilir ve başka bağlamlarda yeniden kullanılabilir.

Gruplama örneği indirgemenin genelliğini gösterir: birikeç bir sayı olmak zorunda değildir,
bir nesne de olabilir. Birikecin `Object.create(null)` ile kurulması bilinçlidir — sensör
adları veri kaynağından geldiği için, zincirden gelen adlarla çakışma riski böylece
ortadan kalkar.

Son iki satır fonksiyonun sıradan bir değer olduğunu doğrular: türü sorgulanabilir,
parametre sayısı okunabilir, bir değişkende saklanabilir.

## Fonksiyon Döndüren Fonksiyonlar

İkinci biçim, bir fonksiyonu üreten fonksiyondur. Üretilen fonksiyon, üreticinin
parametrelerini kapanışla taşır; böylece davranışı dışarıdan ayarlanmış özel bir işlev
elde edilir.

```js
function anahtaraGore(anahtarIslevi, ters = false) {
  const yon = ters ? -1 : 1;
  return (a, b) => {
    const solAnahtar = anahtarIslevi(a);
    const sagAnahtar = anahtarIslevi(b);
    if (solAnahtar < sagAnahtar) return -1 * yon;
    if (solAnahtar > sagAnahtar) return 1 * yon;
    return 0;
  };
}

const kayitlar = [
  { sensor: "S-02", deger: 19.8 },
  { sensor: "S-01", deger: 25.1 },
  { sensor: "S-03", deger: 18.2 },
  { sensor: "S-01", deger: 21.4 },
];

const bicim = (liste) => liste.map((k) => `${k.sensor}:${k.deger}`).join(" ");

console.log(bicim([...kayitlar].sort(anahtaraGore((k) => k.deger))));
console.log(bicim([...kayitlar].sort(anahtaraGore((k) => k.deger, true))));
console.log(bicim([...kayitlar].sort(anahtaraGore((k) => k.sensor))));
console.log(bicim(kayitlar));
```

```
S-03:18.2 S-02:19.8 S-01:21.4 S-01:25.1
S-01:25.1 S-01:21.4 S-02:19.8 S-03:18.2
S-01:25.1 S-01:21.4 S-02:19.8 S-03:18.2
S-02:19.8 S-01:25.1 S-03:18.2 S-01:21.4
```

Tek bir `anahtaraGore` işlevi, üç farklı sıralama ölçütü üretir. Karşılaştırma mantığı bir
kez yazılır; değişen tek şey anahtarın nasıl çıkarıldığıdır. Bu, Algoritmalar kursundaki
Sıralama Algoritması Seçimi dersinde geçen bileşik anahtar fikrinin fonksiyon düzeyindeki
karşılığıdır.

Üçüncü satır sıralamanın **kararlılığını** gösterir: sensör adına göre sıralandığında iki
`S-01` kaydı, girdideki göreli sıralarını korur. Son satır ise kaynağın değişmediğini
doğrular — sıralama yerinde çalıştığı için her çağrıda yayma ile kopya alınmıştır.

## Bileşim

Fonksiyon döndürmenin ikinci kullanımı, birden çok dönüşümü tek bir işleve
**bileştirmektir**. Her adım kendi başına yazılır, sıra bir kez kurulur.

```js
function kalibratorUret(kayma, carpan) {
  return (hamDeger) => (hamDeger + kayma) * carpan;
}

function birlestir(...islevler) {
  return (baslangic) => islevler.reduce((deger, islev) => islev(deger), baslangic);
}

const sensorS01 = kalibratorUret(-0.4, 1.02);
const sensorS02 = kalibratorUret(0.15, 1.0);

console.log(sensorS01(21.4).toFixed(3));
console.log(sensorS02(19.8).toFixed(3));

const yuvarla = (deger) => Math.round(deger * 10) / 10;
const santigrattanFahrenhayta = (deger) => deger * 1.8 + 32;

const boruHatti = birlestir(sensorS01, yuvarla, santigrattanFahrenhayta, yuvarla);

console.log(boruHatti(21.4));
console.log(boruHatti(19.8));
console.log(birlestir()(5));
```

```
21.420
19.950
70.5
67.6
5
```

`birlestir` işlevinin kendisi de bir indirgemedir: başlangıç değeri girdi, birikeç işlemi
"sıradaki işlevi uygula". Argümansız çağrıldığında birim işlevi üretir — hiçbir dönüşüm
uygulanmaz — ve bu, bileşimin doğru tanımlandığının göstergesidir.

`kalibratorUret` ile `bind` ile yapılan kısmi uygulama aynı sonucu verir. Fark okunurlukta
ve bağlamdadır: kapanışlı biçim `this` kullanmaz, hangi parametrenin sabitlendiği adından
bellidir ve bağlanma kurallarının hiçbirine tabi değildir.

## Yöntemi Değer Olarak Aktarmak

Yüksek mertebeden bir fonksiyona bir **yöntem** verildiğinde, önceki derslerdeki kopma
sorunu geri döner: aktarılan şey fonksiyondur, bulunduğu nesne değil.

```js
class OlcumKaydi {
  constructor(sensor, deger) {
    this.sensor = sensor;
    this.deger = deger;
  }
  etiket() {
    return `${this.sensor}:${this.deger}`;
  }
}

const kayitlar = [new OlcumKaydi("S-01", 21.4), new OlcumKaydi("S-02", 19.8)];

try {
  console.log(kayitlar.map(OlcumKaydi.prototype.etiket).join(" "));
} catch (hata) {
  console.log(`dogrudan yontem: ${hata.constructor.name}`);
}

console.log(kayitlar.map((kayit) => kayit.etiket()).join(" "));
console.log(kayitlar.map(Function.prototype.call, OlcumKaydi.prototype.etiket).join(" "));

function uygulaHepsine(liste, islev, baglam) {
  const sonuc = [];
  for (const oge of liste) sonuc.push(islev.call(baglam, oge));
  return sonuc;
}

console.log(uygulaHepsine([1, 2, 3], function (sayi) {
  return sayi * this.carpan;
}, { carpan: 10 }).join(","));
```

```
dogrudan yontem: TypeError
S-01:21.4 S-02:19.8
S-01:21.4 S-02:19.8
10,20,30
```

Prototipteki yöntem doğrudan verildiğinde `this` bağlanmaz. En okunur çözüm çağrıyı bir ok
fonksiyonuyla sarmaktır. Üçüncü satır ise `map` işlevinin bağlam parametresini kullanan
daha dolaylı bir yoldur: eşlenen fonksiyon `call` olur, bağlam da asıl yöntem; her öge
`call` işleminin ilk argümanı olarak aktarılır. Yazımı kısa, okunması zordur; kısalık
uğruna okunurluktan vazgeçmenin iyi bir örneğidir.

Son bölüm, kendi yazdığınız yüksek mertebeden fonksiyonlarda bağlam desteğinin nasıl
verileceğini gösterir: `islev.call(baglam, oge)` biçimi, yerleşik dizi yöntemlerinin
ikinci parametresiyle aynı sözleşmeyi kurar.

## Davranış Ekleyen Sarmalayıcılar

Üçüncü biçim, bir fonksiyonu alıp aynı arayüzü sunan ama davranışı genişletilmiş bir
fonksiyon döndürmektir. Kapanışlar dersindeki not alma sarmalayıcısı bunun bir örneğiydi;
kalıp geneldir.

```js
function birKere(islev) {
  let calisti = false;
  let sonuc;
  return function (...argumanlar) {
    if (!calisti) {
      calisti = true;
      sonuc = islev.apply(this, argumanlar);
    }
    return sonuc;
  };
}

function dogrulayarakSar(islev, gecerliMi, ileti) {
  return function (...argumanlar) {
    if (!argumanlar.every(gecerliMi)) throw new RangeError(ileti);
    return islev.apply(this, argumanlar);
  };
}

let kurulumSayisi = 0;
const kurulumYap = birKere((sensor) => {
  kurulumSayisi += 1;
  return `${sensor} kuruldu`;
});

console.log(kurulumYap("S-01"));
console.log(kurulumYap("S-02"));
console.log(kurulumSayisi);

const guvenliOrtalama = dogrulayarakSar(
  (...degerler) => degerler.reduce((t, d) => t + d, 0) / degerler.length,
  (deger) => typeof deger === "number" && Number.isFinite(deger),
  "tum degerler sonlu sayi olmalidir",
);

console.log(guvenliOrtalama(21.4, 19.8, 25.1).toFixed(3));
try {
  guvenliOrtalama(21.4, "yirmi");
} catch (hata) {
  console.log(`${hata.constructor.name}: ${hata.message}`);
}

const kayit = {
  sensor: "S-01",
  ozet: dogrulayarakSar(
    function (onEk) {
      return `${onEk}-${this.sensor}`;
    },
    (a) => typeof a === "string",
    "on ek dizgi olmalidir",
  ),
};
console.log(kayit.ozet("olcum"));
```

```
S-01 kuruldu
S-01 kuruldu
1
22.100
RangeError: tum degerler sonlu sayi olmalidir
olcum-S-01
```

İki sarmalayıcı da üç kurala uyar. Aynı parametreleri kabul ederler — bu yüzden kalan
parametreler kullanılır. Aynı dönüş değerini verirler. Ve bağlamı korurlar: gövdeleri ok
fonksiyonu değil işlev ifadesidir, `apply` çağrısında `this` aktarılır. Son bölüm bu
üçüncü kuralın sonucudur — sarmalanmış fonksiyon bir nesnenin yöntemi olarak
çağrıldığında `this` doğru nesneye bağlanır.

Sarmalayıcı ok fonksiyonuyla yazılsaydı `this` sarmalayıcının tanımlandığı kapsamdan
gelirdi ve yöntem olarak kullanılamazdı. Ok fonksiyonlarının sınırı burada da geçerlidir.

## Özet

- Fonksiyon bir değerdir: değişkende saklanır, argüman olarak verilir, döndürülür ve
  özellik taşır.
- Süzme, eşleme ve indirgeme, bir koleksiyon üzerindeki işlemin ölçütünü dışarıdan alarak
  sorumlulukları ayırır; indirgemenin birikeci nesne de olabilir.
- Fonksiyon döndüren fonksiyonlar, parametreleri kapanışla taşıyan özelleşmiş işlevler
  üretir; sıralama ölçütleri ve kalibratörler bunun tipik örnekleridir.
- Bileşim, tek tek yazılmış dönüşümleri sırayla uygulayan bir indirgemedir.
- Yöntemi doğrudan yüksek mertebeden bir fonksiyona vermek bağı koparır; çağrıyı saran bir
  ok fonksiyonu en okunur çözümdür.
- Sarmalayıcılar aynı parametreleri ve dönüş değerini korumalı, `apply` ile bağlamı
  aktarmalıdır; bu yüzden ok fonksiyonu olarak yazılamazlar.

## Sonraki Adım

Bu derste gruplama yapılırken birikeç `Object.create(null)` ile kuruldu; nedeni, sensör
adlarının zincirden gelen adlarla çakışabilmesiydi. Aynı önlem kursun ilk dersinde de,
kapanışlardaki önbellekte de gerekti. Nesneyi sözlük olarak kullanmanın bu ve başka
sınırları vardır: anahtarlar dizgiye çevrilir, sıra garantisi kısıtlıdır, eleman sayısı
doğrudan okunamaz. Sonraki konu, dilin bu iş için ayrılmış türlerini — anahtarlı ve tekil
koleksiyonları — tanıtarak başlayacak.
