Skip to content

Instantly share code, notes, and snippets.

@cemtopkaya
Created December 22, 2024 09:47
Show Gist options
  • Save cemtopkaya/e1a7473e784fb949d4d4740bbba4caa9 to your computer and use it in GitHub Desktop.
Save cemtopkaya/e1a7473e784fb949d4d4740bbba4caa9 to your computer and use it in GitHub Desktop.
Javascript ve nodejs soruları
@cemtopkaya
Copy link
Author

Soru:

Aşağıdaki kod parçacığını inceleyin ve ilgili soruları cevaplayın:

function Timer() {
  this.seconds = 0;

  // Arrow function ile tanımlı bir interval
  this.startArrow = function () {
    setInterval(() => {
      this.seconds++;
      console.log("Arrow:", this.seconds);
    }, 1000);
  };

  // Klasik function ile tanımlı bir interval
  this.startRegular = function () {
    setInterval(function () {
      this.seconds++;
      console.log("Regular:", this.seconds);
    }, 1000);
  };

  // self ile çözüm denemesi
  this.startWithSelf = function () {
    const self = this;
    setInterval(function () {
      self.seconds++;
      console.log("Self:", self.seconds);
    }, 1000);
  };
}

// Timer nesnesini başlat ve fonksiyonları sırayla çalıştır
const timer = new Timer();
timer.startArrow();
timer.startRegular();
setTimeout(() => {
  timer.startWithSelf();
}, 3000);

Sorular:

  1. startArrow, startRegular, ve startWithSelf fonksiyonları arasındaki farklar nelerdir? Çıktılar nasıl olur?
  2. this bağlamı startRegular fonksiyonunda neden beklenildiği gibi çalışmaz? Bunun çözümü için bind yöntemini nasıl kullanabilirsiniz?
  3. self değişkeni hangi durumda gerekli olur ve neden işe yarar? JavaScript'in this bağlamı ile self arasındaki farkı açıklayın.
  4. Bonus: startWithSelf fonksiyonunu self kullanmadan, modern ES6+ yöntemlerini kullanarak yeniden yazabilir misiniz?

Beklenen Cevaplar:

1. Çıktı Analizi:

Kod çalıştırıldığında aşağıdaki çıktılar oluşacaktır:

  • startArrow: Arrow fonksiyonu this bağlamını lexical (tanımlandığı yerin bağlamı) olarak kullanır. Yani, this burada Timer nesnesini işaret eder ve seconds artışını doğru şekilde yapar. Örnek çıktı:

    Arrow: 1
    Arrow: 2
    Arrow: 3
    
  • startRegular: Klasik fonksiyon this bağlamını runtime'da belirler. Burada setInterval global bir fonksiyon olduğu için this undefined (strict mode) veya window (non-strict mode) olur. Dolayısıyla this.seconds artırılamaz ve hata alabilirsiniz. Örnek çıktı:

    Uncaught TypeError: Cannot read properties of undefined (reading 'seconds')
    
  • startWithSelf: self değişkeni dıştaki fonksiyonun this bağlamını tutar ve içeride erişilebilir hale getirir. Bu, Timer nesnesinin seconds değerini artırmayı sağlar. Örnek çıktı:

    Self: 1
    Self: 2
    Self: 3
    

2. this Bağlamı ve startRegular:

startRegular fonksiyonundaki this sorunu bind kullanılarak çözülebilir:

this.startRegular = function () {
  setInterval(function () {
    this.seconds++;
    console.log("Regular with bind:", this.seconds);
  }.bind(this), 1000);
};

Bu çözümde bind(this) ifadesi, setInterval'in callback'inin this bağlamını Timer nesnesine sabitler.


3. self Kullanımının Gerekliliği:

self değişkeni, ES6 öncesi dönemde this bağlamının kaybolmasını önlemek için yaygın bir çözümdü. ES6+ ile arrow fonksiyonlar bu ihtiyacı büyük ölçüde ortadan kaldırdı. Ancak, arrow fonksiyon kullanılamadığı durumlarda (örneğin, eski tarayıcı desteği gerekirse) self hâlâ geçerli bir çözümdür.


4. Modern ES6+ ile Yeniden Yazım:

startWithSelf fonksiyonu modern bir arrow fonksiyon ile şu şekilde yeniden yazılabilir:

this.startWithSelf = function () {
  setInterval(() => {
    this.seconds++;
    console.log("Modern Self (Arrow):", this.seconds);
  }, 1000);
};

Bu yöntem hem okunabilirliği artırır hem de this bağlamını doğru şekilde işler.


Görüşme Yapan İçin Değerlendirme:

Adayın bu soruyu yanıtlarken şu konulara hakimiyetini değerlendiriniz:

  • this bağlamını anlaması ve farklı bağlamlarda nasıl değiştiğini açıklayabilmesi.
  • Klasik fonksiyonlar ile arrow fonksiyonlar arasındaki farkları net şekilde ifade edebilmesi.
  • self gibi eski yöntemlerin ne zaman gerekli olduğunu ve modern alternatiflerini açıklayabilmesi.
  • JavaScript'in execution context mantığını derinlemesine kavrayıp kavrayamadığı.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment