CodeBlanks Logo Icon CodeBlanks

Method decorator

Metot decorator'larını yazmayı öğrenirsin.

Method decorator

Metot decorator'u, bir metot bildirisinin hemen üstüne yazılır ve üç argüman alır: (target, propertyKey, descriptor). target sınıf prototype'ı, propertyKey metot adı, descriptor ise metot tanımını tutan nesnedir. Descriptor üzerinde değişiklik yaparak metodun davranışını değiştirebilirsin.

function LogMethod(
  target: any,
  key: string,
  descriptor: PropertyDescriptor
) {
  const original = descriptor.value;
  descriptor.value = function(...args: any[]) {
    console.log("çağrıldı");
    return original.apply(this, args);
  };
}

descriptor.value

descriptor.value, metot fonksiyonunun kendisini tutar. Orijinal fonksiyonu bir değişkene kaydedip descriptor.value'yu yeni bir fonksiyonla değiştirirsen, metot çağrıldığında artık yeni fonksiyon çalışır. İçinden original.apply(this, args) ile orijinali çağırabilirsin; böylece hem loglama ekler hem eski davranışı korursun.

Uygulama Metot çağrısını logla

LogMethod decorator'u yaz: (target: any, key: string, descriptor: PropertyDescriptor) alsın. Gövdede original değişkenine descriptor.value'yu ata; descriptor.value'yı, console.log("çağrıldı") yazdırıp original.apply(this, args) döndüren bir fonksiyonla değiştir. Hesap sınıfı yaz; topla(a: number, b: number): number metodu a + b döndürsün. Object.getOwnPropertyDescriptor ile topla'nın descriptor'unu al, LogMethod'u elle uygula, Object.defineProperty ile geri yaz. Hesap örneği üzerinde toplama metoduyla 2 ve 3 değerlerini topla ve sonucu yazdır.

Başlangıç kodu

index.ts
// LogMethod decorator'unu yaz: target, key, descriptor alır
// original = descriptor.value kaydet
// descriptor.value'yu loglayan ve original.apply döndüren fonksiyonla değiştir
// Hesap sınıfı, topla(a, b) metodu a+b döndürsün
// topla'nın descriptor'unu Object.getOwnPropertyDescriptor ile al
// LogMethod'u elle uygula, Object.defineProperty ile geri yaz
// Hesap örneği üzerinde toplama metoduyla 2 ve 3'ü topla, sonucu yazdır

Örnek çözüm

index.ts
function LogMethod(target: any, key: string, descriptor: PropertyDescriptor): void {
  const original = descriptor.value;
  descriptor.value = function(...args: any[]) {
    console.log("çağrıldı");
    return original.apply(this, args);
  };
}

class Hesap {
  topla(a: number, b: number): number {
    return a + b;
  }
}

const desc = Object.getOwnPropertyDescriptor(Hesap.prototype, "topla")!;
LogMethod(Hesap.prototype, "topla", desc);
Object.defineProperty(Hesap.prototype, "topla", desc);
console.log(new Hesap().topla(2, 3));

Beklenen çıktı

çağrıldı
5

Soru ve cevaplar

Dersin sorularını cevaplarıyla birlikte inceleyebilirsin. Kendini denemek istersen dersi interaktif olarak çöz.

1 Bir metot decorator'u hangi üç argümanı alır?

  • (target, propertyKey)
  • (constructor, args)
  • (instance, key, value)
  • (target, propertyKey, descriptor) Doğru cevap

Açıklama: Metot decorator'u üç argüman alır: target (prototype), propertyKey (metot adı) ve descriptor (metot tanım nesnesi). İki argüman property decorator'a, constructor sınıf decorator'una aittir.

2 Orijinal metodu kaydet

Soru
function LogMethod(target: any, key: string, descriptor: PropertyDescriptor): void {
  const original = ____;
  descriptor.value = function(...args: any[]) {
    return original.apply(this, args);
  };
}
Cevap
function LogMethod(target: any, key: string, descriptor: PropertyDescriptor): void {
  const original = descriptor.value;
  descriptor.value = function(...args: any[]) {
    return original.apply(this, args);
  };
}

Açıklama: Metot fonksiyonu descriptor.value'da bulunur. target prototype'tır, key bir string'tir, this ise çağrı bağlamına bağlıdır; hiçbiri metot fonksiyonunu doğrudan tutmaz.

3 Metot decorator parçaları

Kavram Anlamı
target Sınıf prototype'ı
propertyKey Metot adı
descriptor Metot tanım nesnesi
descriptor.value Metot fonksiyonunun kendisi

Orta seviye bölümündeki tüm dersler