Pratik JavaScript Soruları

Bu yazımızda JavaScript bilginizi test edip bu bilgileriniz pekiştirebileceğiniz bir soru-cevap etkinliği derledik.

  1. tripleAdd(30)(40)(50) örneğini kodlayın
  1. JavaScript dinamik bir dil (dynamic language) midir?

JavaScript dinamik bir dildir, yani bu demektir ki değişkenlerin veri tipleri “runtime” esnasında değişebilir. Aşağıdaki örnekte, x “number” bir veri tipi olarak tanımlanmış ama sonrasında “string” ve “boolean” veri tiplerine dönüştürülebilmiştir:

  1. JavaScript “forwards-compatible” (ileriye dönük uyumlu) bir dil midir?

Birçok kişinin böyle olmasını dilemesine ve hatta yanlış bir şekilde böyle olduğu efsanesine inanmasına rağmen JavaScript aslında “forwards-compatible” (ileriye dönük uyumlu) değildir. Bilakis “geriye dönük uyumlu” (backwards compatibility) bir dildir.

Mesela HTML ve CSS “ileriye dönük uyumludur” ancak onlar da “geriye dönük uyumlu” (backwards compatibility) değildir.

  1. JavaScript “interpreted” (yorumlanabilir) bir dil mi yoksa “compiled” (derlenebilir) bir dil mi?

JavaScript “interpreted” (yorumlanabilir) bir dildir. Yani, JavaScript kodu çalıştırıldığında, yorumlayıcı kodu okur ve ardından yorumlar, sonuçları hesaplar ve ona göre çalıştırır.

Modern JavaScript motorları aynı zamanda JIT (just in time) derleme teknolojisi de kullanır. Bu ise, JavaScript kodunun yorumlanırken aynı zamanda bir JIT derleyicisi tarafından makine koduna derlenerek çalıştırıldığı anlamına gelir. JIT derleme, kodun bir kısmını veya tamamını makine diline çevirerek performansı arttırır ve yorumlama maliyetini azaltır.

Özetle, JavaScript genel hatlarıyla derlenmiş bir dildir diyebiliriz, JavaScript programı çalıştırmadan önce işler ve doğrular (herhangi bir hatayı bildirir!). Bu da onu hem yorumlanabilir hem de JIT derlemesi yapılan bir dil yapar.

  1. JavaScript veri tiplerini nasıl belirler?

JavaScript, atanan (assign) değere bağlı olarak veri tipini belirler. Bu demektir ki eğer 10 değeri atarsanız ilgili değişkenin sayısal veri tipinde olduğunu anlayacaktır.

  1. JavaScript’te veri tipi nasıl kontrol edilir?

JavaScript’te veri tipini kontrol etmek için “typeof” metodu kullanılır. Örneğin:

  1. JavaScript’te kaç farklı veri tipi bulunmaktadır?

JavaScript’te toplam sekiz farklı veri tipi bulunmaktadır ve bu sekiz veri tipi İlkel (Primitive) ve Nesneler / İlkel olmayan (Non Primitive) olmak üzere 2 kategoriye ayrılır.

  1. JavaScript’te ilkel veri tipleri (primitive) nelerdir?
  • string
  • number
  • bigint
  • boolean
  • null
  • undefined
  • symbol
  1. JavaScript’te ilkel olmayan veri tipleri (non primitive) nelerdir?

JavaScript’te nesneler (array, function haliyle bu veri tipine girer) non primitive veri tipleridir.

  1. “null” ve “undefined” arasındaki farklar nelerdir?
  • Undefined: Bir değişkenin oluşturulduğunu ancak o değişkene herhangi bir değerin atanmadığını (assign) ifade eder. Bunu, bir gezegenin keşfedildiği ama henüz bir adının verilmediği duruma benzetebiliriz. Programlamada “undefined”, bir değişkenin tanımlandığını ama henüz bir değer ataması yapılmadığını gösterir. Yani gezegen orada, fark edilmiş ama henüz “bu gezegen şudur” diye bir tanım yok.
  • Null: bir değişkenin atanmış (assign) ancak içeriği boş olarak ayarlandığı anlamına gelir. Yani bir değişkenin değerinin null olması, bu değişkenin bir değeri olduğu ancak bu değerin hiçbir şey ifade etmediği, verinin yokluğu anlamına gelir. Big Bang öncesine “null” demek, bu kavramı daha iyi açıklıyor. Programlamada “null”, hiçbir şeyin olmadığını, değerin bilinçli olarak boş bırakıldığını ifade eder. Big Bang öncesi için “null” kullanmak, o noktada henüz bir evrenin veya içeriğinin olmadığını, yani hiçbir şeyin tanımlı olmadığını gösterir. İşte bu, programlamada bir değişkenin bilinçli olarak hiçbir değere sahip olmadığını belirtir.
  1. JavaScript’te “hoisting” kavramı ne işe yarar? Ayrıca “variable hoisting” ile “function hoisting” kavramlarını açıklayınız.

JavaScript’te “hoisting” kavramı, değişkenlerin ve fonksiyon tanımlarının kodun başında sanal olarak “kaldırılması” anlamına gelir. Bu, kodun yürütülmesinden önce değişkenlerin ve fonksiyonların en üst kısma taşındığı anlamına gelmez; daha çok, değişkenlerin ve fonksiyonların tanımının kapsamın (scope) en üstüne çıkarılması olarak düşünülebilir.

  • Variable Hoisting: JavaScript’te, değişkenleri (var, let, const) tanımladığınızda, var ile tanımlanan değişkenler hoisted olur. Yani, var ile tanımlanan bir değişkenin tanımının fonksiyonun veya global kapsamın en üstüne çıkarıldığı anlamına gelir. Ancak, bu sadece değişken tanımını kapsar; değer ataması hoisted olmaz.

Bu kodda, x değişkeni undefined olarak gösterilir çünkü sadece tanımı hoisted edilir. Değer ataması (x = 5) hala kodun o kısmında gerçekleşir.

let ve const ile tanımlanan değişkenler ise modern JavaScript’te hoisting’e farklı bir şekilde tabidir. Bu değişkenler de kapsamın başına hoisted edilir, ancak “temporal dead zone” olarak adlandırılan ve değişkenin tanımlandığı satıra kadar olan bölgede erişilemezler. Bu, let ve const kullanılarak tanımlanan değişkenlere, tanımlandıkları satıra kadar erişilemeyeceği anlamına gelir.

  • Fonksiyon hoisting: fonksiyon tanımlarının kapsamın en üstüne çıkarılması durumudur. Fonksiyon ifadeleri (fonksiyonun bir değişkene değer olarak atanması) ve ok fonksiyonları (arrow functions) bu kurala tabi değildir, ancak normal fonksiyon tanımları “hoisted” olur. Örneğin:
  1. Global değişken (global variable) ne demektir?

Global değişkenler, web sayfası veya belge boyunca erişilebilen değişkenlerdir.

  1. Global değişkenlerle ilgili sorunlar nelerdir?

Global değişkenler her yerden erişilebilir olduğu için karışıklık çıkartır ve hata ayıklamayı (debugging) zorlaştırır.

  1. JavaScript’te “var“, “let” ve “const” arasındaki fark nedir?

JavaScript’te var, let ve const anahtar kelimeleri, değişkenleri tanımlamak için kullanılır, ancak aralarında önemli farklar bulunur. Bu farklar, kapsam (scope), hoisting, ve yeniden atama kuralları üzerine kuruludur.

Detaylı anlatımı ilgili derste yaptık.

  1. Var, let veya const anahtar kelimeleri olmadan değişken bildirimi yapılabilir mi?

Evet yapılabilir. Örneğin aşağıdaki gibi bir değişken ataması yapıldığında bu var x = 10; şeklinde tanımlanmış gibi algılanır.

  1. Global değişkenlerden nasıl kaçınabiliriz?

Şu üç metod ile aşılabilir:

  • Namespace
  • Closures
  • IIFE
  1. JavaScript’te “call stack” (çağrı yığını) nedir?

Çağrı yığını (call stack), yürütülecek fonksiyonların kaydını tutar. “LIFO” (last in first out) yürütme yöntemini izler.

  1. JavaScript “multi-threaded” bir dil midir?

Hayır. JavaScript “single-threaded” bir dildir ve asenkron davranışlar genellikle olay döngüsü (event loop) ve geri çağırma fonksiyonları (callbacks) ile yönetilir. Bu, JavaScript’in aynı anda sadece bir işi işleyebileceği anlamına gelir.

  1. JavaScript’te “blocking call” (engelleyici çağrı) nedir?

Engelleyici çağrı (blocking call), bir işlem tamamlanana kadar diğer işlemlerin beklemek zorunda olduğu bir çağrıdır. Bu tür bir çağrı, kodun akışını engeller ve ilgili işlem tamamlanmadan devam etmez. Bu nedenle, engelleyici çağrılar, uygulamaların tepkisiz veya yavaş çalışmasına neden olabilir.

Modern JavaScript uygulamaları, engelleyici çağrıların kullanımını azaltmak için genellikle asenkron işlem modeli kullanır. Bu modelde, uzun süreli işlemler asenkron fonksiyonlar veya promise’ler kullanarak gerçekleştirilir ve diğer işlemleri bekletilmez. Bu sayede uygulamalar daha hızlı ve daha verimli hale gelir.

  1. JavaScrip’te IIFE nedir ve ne işe yarar?

javaScrip’te IIFE; Immediately Invoked Function Expressions kelimelerinin kısaltmasını temsil etmektedir. Bu yapı Türkçeye Anında Çağrılan Fonksiyonlar anlamına gelmektedir. Bu fonksiyonlar oluşturulduğu anda çalıştıkları için birtakım avantajlara sahiptir:

  • IIFE ile oluşturulan değişkenler dış dünya tarafından görülmez. Yani bu demektir ki bir kod bloğunu fonksiyonun kapsamına sokarak değişkenlerin ve fonksiyonların global kapsama (global scope) sızmasını önler.
  • Modüler bir kullanımı sağladığı için kodun daha temiz, daha düzenli ve daha güvenli olmasını sağlar.
  1. JavaScript’te “closure” kavramı ne işe yarar?

JavaScript’te closure (kapama), bir iç fonksiyonun, dış fonksiyonun değişkenlerine ve kapsamına erişebilmesi olarak tanımlanan bir programlama kavramıdır. Örneğin:

Yukarıdaki kodumuzda counter() fonksiyonu, count değişkenini kapsayan bir closure olarak kodlanmıştır. Böylececounter() fonksiyonu her çağrıldığında, count değişkeninin değerini artırır ve artırılmış değeri döndürür. “Closure” sayesinde, counter() fonksiyonu, count değişkenine erişebilir ve her çağrıldığında count değişkeninin değerini güncelleyebilir. 

  1. JavaScript’te “this” kavramı ne işe yarar?

JavaScript’te this kelimesi, çalıştırılan bir fonksiyonun içinde bulunduğu nesneyi temsil eden bir özelliktir.

Yukarıdaki örnekte, fullName() fonksiyonunun içindeki this kelimesi, person nesnesini temsil etmektedir. Yani person.fullName() çağrısı yapıldığında, this.firstName ve this.lastName özellikleri, person nesnesinin özelliklerine erişir ve John Doe stringini döndürür. Bu sayede, person nesnesi içindeki özellikler, this kelimesi kullanılarak kullanılabilir hale gelir.

  1. JavaScript’te “arrow” fonksiyonu var mıdır?

Fat arrow” olarak da adlandırılan “arrow” fonksiyonları, “function” anahtar kelimesi yerine “=>” işareti ile kullanılır.

  1. JavaScript’teki “abstract equality (==)” ile “strict equality (===)” arasındaki fark nedir?

soyut eşitlik (==) ile katı eşitlik (===) arasındaki en temel fark “tip” ve “değer” karşılaştırmasıdır. Yani === ile iki değerin hem tipini hem de değeri karşılaştırılırken == ile değerlerin tipleri eşitlenerek sadece değer karşılaştırması yapılır.

Genel olarak, JavaScript’te veri tipleri arasında yapılan karşılaştırmalarda === operatörü tercih edilmelidir. Zira == operatörü ile kod tahmin edilebilirliği zorlaştığı için pek tavsiye edilmez.

Credit: MDN
  1. JavaScript’te “use strict” ifadesi nedir, ne işe yarar?

JavaScript’te "use strict" (katı mod) ifadesi, yazılan kodun daha güvenli, tutarlı ve hata ayıklamasının daha kolay olmasını sağlamak için kullanılan bir yöntemdir. Genel hatlarıyla aşağıdaki gibi bazı davranışları değiştirir:

  • İşlev ve değişken tanımlamalarında var kullanılmazsa, hata verir.
  • Değiştirilemez nesne olan arguments, değiştirilemez olmaktan çıkar.
  • Silinebilir özellikler üzerinde delete operatörü kullanılırsa, hata verir.
  • Global nesnedeki özelliklerin değiştirilmesi veya silinmesi durumunda hata verir.
  • Tanımsız değişkenler kullanılırsa, hata verir.
  1. JavaScript’te “Asynch” çağrılarını nasıl yapabiliriz?

“Async” çağrıları yapmanın üç yolu vardır:

• WebAPI Browser calls.
• Promises
• Worker threads.

  1. JavaScript’te “default parameter” nedir?

JavaScript’te varsayılan parametreler (default parameters), hiçbir değer aktarılmadığında veya tanımlanmadığında fonksiyon parametrelerinin varsayılan değerlerle başlatılmasını sağlar.

  1. JavaScript’te “destructing” kullanımını açıklayınız.

JavaScript’te destructuring, ES6 (ECMAScript 2015) ile tanıtılan bir özelliklerden biri olup dizi (array) veya nesne (object) verilerindeki öğelere daha kolay bir şekilde erişim sağlamak için kullanılır.

Bu özellik, bir dizi veya nesne içindeki elemanları tek tek çıkararak veya özellikleri ayrı ayrı çıkararak değişkenlere atamamızı sağlar.

Destructuring işlemi, atama operatörü (=) ile yapılır ve diziler için iki köşeli parantez ([[]]), nesneler için iki süslü parantez ({{}}) arasında gösterilir.

  1. JavaScript’te “template literal” ne işe yarar açıklayınız.

Template literals, ES6 ile birlikte JavaScript diline eklenen özelliklerden biridir. String ifadelerinin oluşturulmasını daha kolay ve okunaklı hale getiren template literals, ters tırnak (backstick) işareti ile belirtilir ve içerisinde değişkenlerin veya ifadelerin yerleştirilmesine izin verir.

Template literals kullanımı sayesinde, “string” ifadeleri içerisinde değişkenlerin veya ifadelerin yerleştirilmesi daha kolay hale gelir. Bunun için ${} işaretleri kullanılır ve içerisine değişkenler veya ifadeler yazılır.

Ayrıca, template literals kullanarak çok satırlı string ifadeleri oluşturmak da mümkündür. Böylece, tek tırnak veya çift tırnak işaretleriyle uğraşmadan, çok satırlı string ifadeleri oluşturmak kolaylaşır.

  1. JavaScript’te “spread” operatörü ne işe yarar?

JavaScript’te spread operatörü, ES6 (ECMAScript 2015) ile tanıtılmış olup üç nokta () karakteri ile gösterilir. Özellikle dizi (array) veya nesne (object) verilerini kolayca kopyalamak, birleştirmek veya genişletmek için kullanılır. Örneğin:

  1. JavaScript’teki “rest” parametresi ne işe yarar?

JavaScript’te rest parameter, ES6 (ECMAScript 2015) ile tanıtılan özelliklerden biridir ve bir fonksiyona değişken sayıda argüman (argument) geçirmek için kullanılır. Bu özellik, fonksiyon tanımında üç nokta işareti () kullanarak belirtilir. Bu sayede bir fonksiyonun değişken sayıda argüman almasını sağlar ve bunları bir dizi (array) olarak toplar.

“Rest” parametresi sayesinde tek tek bu argümanları girmek yerine bu işlem otomatik bir şekilde yapılmaktadır.

  1. Bir fonksiyonun kaç kere çağrıldığını sayan örnek bir “counter fonksiyonu” yazın.
  1. Aşağıdaki fonksiyonu “curry function” şeklinde yazınız.

Yukarıdaki fonksiyonu “curry” şeklinde aşağıdaki gibi yazabiliriz:

  1. JavaScript’te “higher-order function” ne anlama gelir?
  1. passing data by value” (değer ile veri aktarma) ve “passing data by reference” (referans ile veri aktarma) kavramlarını açıklayınız.

Passing data by value” durumunda, bir fonksiyona argüman olarak verilen değerin bir kopyası oluşturulur. Bu durum, JavaScript’teki ilkel tipler (string, number, boolean, null, undefined, ve symbol) için geçerlidir. Fonksiyona aktarılan değerlerin kopyaları oluşturulduğu için, fonksiyon içinde bu değerler üzerinde yapılan değişiklikler orijinal değerleri etkilemez.

Yukarıdaki örnekte, newNum değişkeninin değeri change fonksiyonuna kopya olarak geçirilir ve fonksiyon içinde yapılan değişiklik orijinal değeri etkilemez.

Passing data by reference” ise, nesne tiplerinde (object, array, function) görülür. Bu durumda, fonksiyona argüman olarak verilen değerin kendisi değil, o değere referans (bellekteki adresi) geçirilir. Bu nedenle, fonksiyon içinde bu tür veri yapıları üzerinde yapılan değişiklikler, orijinal veri yapısını da etkiler.

Bu örnekte, change fonksiyonuna person nesnesi referans olarak geçirilir. Fonksiyon içinde yapılan değişiklik (obj.name‘in “Yeni Ad” olarak değiştirilmesi), person nesnesinin orijinal referansını etkilediği için, fonksiyonun dışında person nesnesinin name özelliği de “Yeni Ad” olarak güncellenmiş olur.

  1. JSON nedir, ne işe yarar ve hangi veri tipleri ile kullanılır açıklayınız.

Açılımı JavaScript Object Notation şeklinde olan JSON bir veri değişim formatıdır ve verileri metin biçiminde temsil etmeye yarar. Genel olarak verileri depolamak, değiş tokuş etmek veya web uygulamalarında kullanılır.

JSON şu veri tiplerini içerir:

  • string: Çift tırnak içindeki metinler. (❗ Tek tırnak şeklinde kullanılamaz.)
  • number: Tam sayılar, ondalık sayılar veya bilimsel gösterimli sayılar.
  • boolean: true veya false değerlerini ifade eder.
  • null: Bir değerin eksik olduğunu belirtmek için kullanılır.
  • object: Çift süslü parantez {} arasında tanımlanan bir veri koleksiyonu. Bu nesneler, anahtar-değer çiftleri şeklinde tanımlanır. Bu değer çiftleri de çift tırnak içinde yazılır.
  • array: Köşeli parantez [] içinde tanımlanan bir veri koleksiyonudur. Bu nesneler, sıralı elemanlar listesi şeklinde tanımlanır. Örneğin:
  1. JavaScript ile nesne oluşturabilmek için hangi yöntemler kullanılır?

Object Literal: Bu yöntem, bir nesne tanımlama sözdizimi kullanarak bir nesne oluşturur. Nesnenin özellikleri ve değerleri süslü parantez {} içinde belirtilir. Örneğin:

Constructor Function (Yapıcı fonksiyon): Bu yöntem, bir yapıcı fonksiyon kullanarak bir nesne oluşturur. Yapıcı fonksiyon, nesnenin özelliklerini ve değerlerini belirler.

Object.create() methodu: Bu yöntem, önceden var olan nesneyi bir prototip olarak kullanarak yeni bir nesne oluşturur.

  1. Aşağıdaki programın çıktısı hangi sıralamada olur?

  1. Aşağıdaki kod yapısı çıktı olarak hangi data tiplerini verir?
  1. JavaScript’te “bind()” yöntemi ne işe yarar?

JavaScript’te bind() metodu, bir fonksiyonun bağlamını (context) belirlemeye ve yeni bir fonksiyon oluşturmaya yarayan bir metottur. Bağlama işlemi, bir fonksiyonun this değerini belirler.

bind() metodu, özellikle bir fonksiyonu belirli bir bağlama (context) içinde çağırmak istediğinizde kullanışlıdır. Zira bind metodu yeni bir fonksiyon döndürdüğü gibi orijinal fonksiyonu da değiştirmez:

  1. Aşağıdaki program çıktı olarak ne verir?
  1. Aşağıdaki program çıktı olarak ne verir?

Bu beklenmedik sonucun nedeni, virgülden sonra belirli sayıda basamağa sahip kayan noktalı sayıların hesaplanmasındaki işlem kesinliği hatasıdır. Bu hatanın sonucu olarak, 300.3 * 3 ifadesi beklenenden biraz daha az olan 900.9000000000001 değerini döndürür. Bu nedenle, 900.9 === 900.9000000000001 ifadesi false sonucunu verir.

Bu sorunu çözmek için aşağıdaki yöntemlerden biri denenebilir:

  1. Aşağıdaki program çıktı olarak ne verir?
  1. Global kapsamda x adında bir değişken tanımlanır ve 10 değeri atanır.
  2. y fonksiyonu tanımlanır. Bu fonksiyon içinde, x adında başka bir fonksiyon tanımlanır. Bu iç fonksiyon tanımı hoisting nedeniyle y fonksiyonunun başına çıkarılır.
  3. y() fonksiyonu çağrıldığında, x = 100; ifadesi çalıştırılır. Ancak bu durumda x, y fonksiyonunun içinde tanımlanan yerel x fonksiyonunu referans alır. Yani bu atama global kapsamdaki x değişkenini değil, yerel kapsamdaki x fonksiyonunu etkiler.
  4. y fonksiyonundan çıkıldığında, global kapsamdaki x değişkeni hala 10 değerine sahiptir, çünkü y fonksiyonu içinde yapılan atama global x değişkenine değil, yerel x fonksiyonuna yapılmıştır.
  5. Sonuç olarak, console.log(x); ifadesi global kapsamdaki x değişkenini yazdırır ve bu değişkenin değeri 10’dur.

İlgili Makaleler

Bir yanıt yazın

E-posta adresiniz yayınlanmayacak. Gerekli alanlar * ile işaretlenmişlerdir

Başa dön tuşu