Popüler Bir Javascript İşe Alım Sorusu

Medium’da denk geldiğim bir yazıyı buraya aktaracağım bu sefer. Yazıda verilen bir kod parçasının Amazon ve Google gibi büyük firmaların işe alım süreçlerinde sorulduğu söyleniyor. Hemen koda bakalım;

var arr = [10, 12, 15, 21];
for (var i = 0; i < arr.length; i++) {
  setTimeout(function() {
    console.log('Index: ' + i + ', element: ' + arr[i]);
  }, 3000);
}

Soru bu kodun konsola çıktısı nedir? Javascript'e aşina olmayan biri için ilk bakışta basit bir for döngüsü gibi durabilir. Ama setTimeout ve Javascript için Event Loop kavramı hakkında bilgisi olan biri için bir bit yeniği olduğu hemen göze çarpıyor. Bu kod için çıktı şu şekilde;

Index: 4, element: undefined
Index: 4, element: undefined
Index: 4, element: undefined
Index: 4, element: undefined

Peki neden bütün i'ler 4 oldu ve arr içinden eleman çağıramadık?

Döngü içinde kurduğumuz setTimeout'lar döngü bittikten çok sonra işlemeye başlayacaktır ve çalıştığında global scope içindeki i değerini kullanıyor ve bu değere döngü çoktan bittiği için son olarak 4 tanımlanmış oluyor.

Bu sorunun sorulma sebebi ise açık; direk olarak Javascript konseptlerini ölçen bir durum. Yeni başlayan herkesin karşılaşacağı ve tecrübeli birinin çözüm önerisiyle öne çıkacağı basit bir soru aslında.

Basitçe yazdığımız kodun istediğimiz cevabı üretmemesinin sebebi bu. Peki nasıl çözebiliriz bu sorunu? İki yaklaşım var, biri Closure kullanarak diğeri ise ES6 standardında kod yazarak.

var arr = [10, 12, 15, 21];
for (var i = 0; i < arr.length; i++) {
  setTimeout(function(i_local) {
    return function() {
      console.log('The index of this number is: ' + i_local);
    }
  }(i), 3000);
}

İlk çözümde olan şu; setTimeout için verdiğimiz fonksiyonu Closure'a çeviriyoruz yani bir parametre almasını ve bu parametreyi fonksiyon tanımlanırken almasını sağlıyoruz. Böylece i'nin anlık değeri lokal olarak kullanılabilecek ve fonksiyon istediğimiz çıktıyı verecek.

const arr = [10, 12, 15, 21];
for (let i = 0; i < arr.length; i++) {
  setTimeout(function() {
    console.log('The index of this number is: ' + i);
  }, 3000);
}

Diğer olası çözüm ise let anahtar kelimesini kullanarak i'yi tanımlamak olabilir. Let ile tanımlanan değişken için her döngüde farklı bir bağlama sağlanacağı için global olan değil de o anki değerin aktarıldığı bir değişkene erişebileceğiz.

Benzer durum event kullanılırken de yaşanabiliyor. Örneğin döngü içerisinde bir dizi elemana erişip click event'lerine bir işlem tanımladınız fakat hiçbiri çalışmıyorsa yukarıdaki çözümlerden birinin uygulamanız gerekir.

Linkler;
https://medium.com/coderbyte/a-tricky-javascript-interview-question-asked-by-google-and-amazon-48d212890703
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Closures
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/let


Yayımlandı

kategorisi

yazarı:

Etiketler:

Yorumlar

Bir cevap yazın

E-posta hesabınız yayımlanmayacak. Gerekli alanlar * ile işaretlenmişlerdir