-
-
Save cemtopkaya/e1a7473e784fb949d4d4740bbba4caa9 to your computer and use it in GitHub Desktop.
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:
startArrow
,startRegular
, vestartWithSelf
fonksiyonları arasındaki farklar nelerdir? Çıktılar nasıl olur?this
bağlamıstartRegular
fonksiyonunda neden beklenildiği gibi çalışmaz? Bunun çözümü içinbind
yöntemini nasıl kullanabilirsiniz?self
değişkeni hangi durumda gerekli olur ve neden işe yarar? JavaScript'inthis
bağlamı ileself
arasındaki farkı açıklayın.- Bonus:
startWithSelf
fonksiyonunuself
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 fonksiyonuthis
bağlamını lexical (tanımlandığı yerin bağlamı) olarak kullanır. Yani,this
buradaTimer
nesnesini işaret eder veseconds
artışını doğru şekilde yapar. Örnek çıktı:Arrow: 1 Arrow: 2 Arrow: 3
-
startRegular
: Klasik fonksiyonthis
bağlamını runtime'da belirler. BuradasetInterval
global bir fonksiyon olduğu içinthis
undefined
(strict mode) veyawindow
(non-strict mode) olur. Dolayısıylathis.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 fonksiyonunthis
bağlamını tutar ve içeride erişilebilir hale getirir. Bu,Timer
nesnesininseconds
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ığı.
Soru:
Aşağıdaki kod parçacığını inceleyin ve soruları cevaplayın:
Sorular:
console.log
satırı neyi yazdırır? Neden?regularFunction
içinde tanımlananinnerFunction
hangithis
bağlamını kullanır? Buna erişmek için nasıl bir çözüm uygulayabilirsiniz?arrowFunction
içindethis
bağlamı nedenobj
'i göstermez? Bu bağlamı değiştirmek mümkün müdür?outerFunction
ve içindekinestedFunction
ilenestedArrow
'un bağlamları nasıl farklıdır? İkisinin farkını açıklayın.call
yöntemi kullanılarakouterFunction
'un bağlamı değiştirildiğindenestedFunction
venestedArrow
bu bağlamı nasıl etkiler?this
bağlamını değiştirmek içinbind
,call
, veyaapply
yöntemlerinden herhangi birini kullanmadanregularFunction
veinnerFunction
'u bağlamlarını paylaşacak şekilde yeniden yazabilir misiniz?Beklenen Cevaplar:
console.log
ÇıktılarıBu sorular adayın:
call
,apply
, vebind
gibi yöntemleri nasıl kullandığını,Örnek Tartışma Konuları:
innerFunction
için bir çözüm olarakself = this
veyabind
yöntemini öneriyorsa, bunun avantajlarını ve dezavantajlarını tartışabilirsiniz.Biraz fikirleşelim:
JavaScript'te
this
anahtar kelimesinin bağlamı, fonksiyonun nasıl çağrıldığına bağlıdır. Yukarıdaki koddaregularFunction
içinde tanımlananinnerFunction
, kendi bağlamında çağrıldığındathis
anahtar kelimesi, global nesneye (tarayıcıdawindow
, Node.js'teglobal
) referans eder. Bu nedenle,innerFunction
içindethis.name
ifadesi, global bağlamda tanımlı birname
değişkenine erişmeye çalışır.Çözüm Yöntemleri
innerFunction
'ın doğruthis
bağlamını kullanmasını sağlamak için birkaç farklı yaklaşım bulunmaktadır:1.
bind
Metodu KullanımıinnerFunction
'ı çağırmadan öncebind
metodu ile doğru bağlamı belirleyebilirsiniz:2. Arrow Function Kullanımı
Arrow function'lar, tanımlandıkları bağlamın
this
değerini korur. Bu yüzdeninnerFunction
yerine bir arrow function kullanabilirsiniz:3. Değişken Tanımlama ile Erişim
Fonksiyonun başında
this
değerini bir değişkene atayarak da erişebilirsiniz:Sonuç
Bu yöntemlerden herhangi biri,
innerFunction
içinde doğruthis
bağlamını kullanarak istenen sonucu elde etmenizi sağlar. Arrow function kullanmak genellikle en temiz ve okunabilir çözüm olarak tercih edilir.