Skip to content

Bölüm 13 / 20

JavaScript temelleri

Değişken, tip, operatör, koşul, döngü.

15 dakikalık okuma

HTML yapıyı, CSS görünüşü verdi. Davranış JavaScript'in işidir. JavaScript on günde tasarlanmış, sonra dünyanın en çok kullanılan diline dönüşmüş bir dildir; bu geçmiş, bugün hâlâ taşıdığı tuhaflıkların sebebidir. Dili "öğrenmek" birkaç saatlik iştir; güvenilir JavaScript yazmak ise otomatik tip dönüşümünü, hangi karşılaştırmanın ne yaptığını, sayıların neden yanlış toplandığını ve kapsam kurallarını bilmeyi gerektirir. Bu ders sıfırdan başlar ama her başlıkta o başlığın tuzağıyla birlikte ilerler.

01Ne öğreneceksin

  • JavaScript'in nerede çalıştığı ve sayfaya doğru eklenme biçimi
  • var, let, const: kapsam, yukarı kaldırma (hoisting) ve geçici ölü bölge
  • const'un gerçekte neyi sabitlediği
  • Yedi ilkel tip, nesneler ve typeof'un iki bilinen yalanı
  • null ile undefined ayrımı
  • Sayılar: 0.1 + 0.2, NaN, güvenli tam sayı sınırı, BigInt
  • Dizeler: şablon değişmezleri ve Türkçe büyük/küçük harf tuzağı
  • == ile ===; doğruluk değeri olan/olmayan değerler
  • || ile ?? farkı ve ?. zinciri
  • Koşullar, switch'in iki tuzağı, döngü türleri ve hangisi ne zaman
  • Sıkı mod ("use strict") ve modüllerin varsayılan davranışı

02JavaScript nerede çalışır, sayfaya nasıl eklenir

JavaScript, tarayıcının JavaScript motorunda çalışır (Chrome'da V8, Firefox'ta SpiderMonkey). Aynı motor tarayıcı dışında da kullanılır — Node.js budur ve 12. hattın konusudur. Dilin kendisi (ECMAScript) ile tarayıcının sunduğu arayüzler (DOM, fetch, localStorage) farklı şeylerdir: Array ve Math her yerde vardır, document yalnız tarayıcıda.

<!-- Uygulama betiği: ayrıştırmayı durdurmaz, sıra korunur -->
<script src="uygulama.js" defer></script>

<!-- Modül: defer gibi davranır, ayrıca kendi kapsamı ve SIKI MODU vardır -->
<script src="uygulama.js" type="module"></script>

<!-- Bağımsız üçüncü parti: sırası önemsizse -->
<script src="analitik.js" async></script>

1. derste bu tablonun tamamını görmüştün; buradaki pratik kural: uygulama betiklerinde defer ya da type="module". İkisi de belge ayrıştırıldıktan sonra çalıştığı için document.querySelector çağrıların null dönmez.

Öğrenirken en hızlı yol tarayıcı konsoludur (F12 → Console). console.log tek araç değildir: console.table dizileri tablo hâlinde, console.dir nesneyi ağaç hâlinde, console.time/ timeEnd süre ölçer, console.assert yalnız koşul yanlışsa yazar. Değişkeni etiketiyle basmanın kısayolu ise süslü parantezdir: console.log({ toplam, adet }).

03Değişkenler: var, let, const

const vergiOrani = 0.20;      // yeniden ATANAMAZ — varsayılan tercih
let toplam = 0;               // yeniden atanabilir
var eski = "kullanma";        // eski sözdizimi
varletconst
KapsamFonksiyonBlok { }Blok { }
Yeniden bildirimSerbestHataHata
Yeniden atamaSerbestSerbestHata
Bildirimden önce erişimundefinedHata (ölü bölge)Hata
window'a eklenir miEvet (küresel kapsamda)HayırHayır

Yukarı kaldırma (hoisting): bildirimler kapsamın başına taşınmış gibi davranır. var ile bildirilen değişken bildirim satırından önce de erişilebilir ve değeri undefined'dır — bu, hatayı gizler. let ve const de kaldırılır ama bildirime kadar geçici ölü bölgede (temporal dead zone) durur ve erişim hata fırlatır; yani hatayı gösterir.

console.log(a);   // undefined  — sessiz, yanıltıcı
var a = 1;

console.log(b);   // ReferenceError: Cannot access 'b' before initialization
let b = 1;

var'ın fonksiyon kapsamlı olmasının klasik sonucu:

for (var i = 0; i < 3; i++) { setTimeout(() => console.log(i), 0); }
// 3, 3, 3   — tek bir i vardır, döngü bittiğinde 3'tür

for (let i = 0; i < 3; i++) { setTimeout(() => console.log(i), 0); }
// 0, 1, 2   — her yineleme kendi i'sini alır

Bu, 14. derste kapanış (closure) konusunda tekrar karşına çıkacak.

const ne sabitler? Yalnız bağlamayı — yani "bu ad artık başka bir değere işaret edemez". Nesnenin içeriği değişebilir:

const kullanici = { ad: "Ayşe" };
kullanici.ad = "Fatma";       // GEÇERLİ — nesnenin içi değişti
kullanici = {};               // TypeError — bağlama değişemez

const liste = [1, 2];
liste.push(3);                // geçerli
Object.freeze(kullanici);     // yüzeysel dondurma; iç nesneler hâlâ değişebilir

Pratik kural: her değişkeni const ile başlat; yeniden atamak gerektiğinde let'e çevir. var'ı yalnız eski kodu okurken görürsün.

04Tipler

JavaScript dinamik tiplidir: değişkenin değil, değerin tipi vardır ve çalışma anında değişebilir. Yedi ilkel tip ve nesneler vardır:

TipÖrnektypeof
string"metin""string"
number42, 3.14, NaN, Infinity"number"
booleantrue, false"boolean"
undefinedDeğer atanmamış"undefined"
nullBilinçli olarak boş"object" ← dilin bilinen hatası
symbolSymbol("id")"symbol"
bigint9007199254740993n"bigint"
nesne / dizi / fonksiyon{}, [], ()=>{}"object", "object", "function"

typeof null === "object" dilin ilk sürümünden kalma bir hatadır ve geriye dönük uyumluluk için düzeltilmemiştir. İkinci yanılgı: dizi de nesnedir, yani typeof [] === "object". Doğru kontroller:

Array.isArray(x)                    // dizi mi
x === null                          // null mı
typeof x === "function"             // fonksiyon mu
Object.prototype.toString.call(x)   // "[object Date]", "[object Map]" … kesin tip

null ile undefined ayrımı anlamsaldır: undefined "henüz değer yok" (atanmamış değişken, dönmeyen fonksiyon, olmayan özellik), null "bilinçli olarak boş" demektir. API sözleşmelerinde (6. hat) bu ayrım önemlidir: alan yoksa undefined, alan var ama değeri boşsa null. JSON'da undefined yoktur — JSON.stringify undefined değerli özellikleri atlar, null'ları yazar. Bu, "alanı sildim ama sunucuya gitmedi" hatalarının kaynağıdır.

05Sayılar

JavaScript'te tek bir sayı tipi vardır ve IEEE 754 çift duyarlıklı kayan noktadır — yani C#'taki int/decimal ayrımı yoktur. Sonuçları bilinmelidir:

0.1 + 0.2                 // 0.30000000000000004
0.1 + 0.2 === 0.3         // false
(0.1 + 0.2).toFixed(2)    // "0.30"  — DİZE döner

9007199254740992 + 1      // 9007199254740992  — güvenli sınırın ötesi
Number.MAX_SAFE_INTEGER   // 9007199254740991

typeof NaN                // "number"
NaN === NaN               // false  — kendisine bile eşit değil
Number.isNaN(x)           // doğru kontrol
[10, 1, 2].sort()         // [1, 10, 2] — VARSAYILAN SIRALAMA DİZEYE GÖRE

Para ile çalışmak

Kayan nokta hatası yüzünden para tutarları ondalık sayıyla saklanmaz. İki yaygın çözüm: (1) tutarı en küçük birimde tam sayı olarak tut (kuruş: 19,90 TL → 1990) ve yalnız gösterirken böl; (2) ondalık aritmetiği doğru yapan bir kütüphane kullan. Sunucu tarafında karşılığı C#'ta decimal, veritabanında DECIMAL/NUMERIC'tir (7. hat, 6. ders). Biçimlendirme için elle nokta-virgül değiştirmek yerine Intl.NumberFormat kullanılır: new Intl.NumberFormat("tr-TR", { style: "currency", currency: "TRY" }).format(1990/100) → "₺19,90". Aynı aile tarih için Intl.DateTimeFormat, sıralama için Intl.Collator sağlar (4. derste kullanmıştık).

Dizeyi sayıya çevirmenin üç yolu ve farkları:

Number("42")        // 42        Number("42abc") → NaN   (tamamı sayı olmalı)
parseInt("42abc")   // 42        baştan okur, ilk geçersizde durur
parseFloat("3.9km") // 3.9
+"42"               // 42        kısa ama okunurluğu düşük

Number("")          // 0   ← boş dize SIFIRA döner, bu yüzden form girdisinde tuzaktır
parseInt("08")      // 8   (modern; eski tarayıcılarda sekizlik sayılırdı — taban yazmak iyi alışkanlık)
parseInt("0.9")     // 0   ← YUVARLAMAZ, keser

06Dizeler

const ad = "Ayşe";
const mesaj = `Sayın ${ad}, başvurunuz ${new Date().getFullYear()} yılında alınmıştır.`;

// Dizeler DEĞİŞTİRİLEMEZ: her işlem YENİ dize üretir
let s = "abc";
s[0] = "X";        // sessizce hiçbir şey yapmaz
s = "X" + s.slice(1);

"  boşluklu  ".trim()
"a,b,c".split(",")            // ["a","b","c"]
"2026-114".padStart(10, "0")
"ara".includes("r")           // true
"Başvuru".startsWith("Baş")   // true
"abc".at(-1)                  // "c"  — negatif indeks

Türkçe büyük/küçük harf tuzağı

"I".toLowerCase() "i" döndürür — oysa Türkçede "I"nın küçüğü "ı"dır. Aynı biçimde "i".toUpperCase() "I" verir, Türkçede "İ" olmalıdır. Bu, kullanıcı adı karşılaştırmasında, arama filtrelerinde ve büyük/küçük harf duyarsız eşleştirmede gerçek hatalara yol açar: "IŞIK" ile "ışık" eşleşmez. Doğrusu yerel duyarlı sürümlerdir: "IŞIK".toLocaleLowerCase("tr") → "ışık". Aynı şekilde sıralama için localeCompare ya da Intl.Collator("tr") kullanılır. Bu tuzak .NET tarafında da vardır (ToLowerInvariant ile ToLower(tr-TR) ayrımı) ve kurumsal Türkçe projelerin klasik hata kaynağıdır.

07Operatörler ve otomatik dönüşüm

JavaScript, farklı tipleri karşılaştırırken ya da toplarken sessizce dönüştürür. Dilin en çok eleştirilen yanı budur ve kuralları ezberlenmez — kaçınılır.

"5" + 3       // "53"   ← + varsa ve bir taraf dizeyse BİRLEŞTİRME
"5" - 3       // 2      ← diğer aritmetik operatörler sayıya çevirir
"5" * "2"     // 10
[] + {}       // "[object Object]"
[] == false   // true
Karşılaştırma== (gevşek)=== (katı)
1 == "1"true — tip dönüştürür1 === "1" → false
0 == falsetruefalse
null == undefinedtruefalse
"" == 0truefalse
NaN == NaNfalsefalse

Kural: her zaman === kullan. Tek meşru istisna x == null'dır; bu tek yazımla hem null hem undefined kontrol edilir ve yaygın kabul görür.

Doğruluk değeri

Koşulda kullanılan her değer bir mantıksal değere çevrilir. Yanlış sayılan yalnız yedi değer vardır, gerisi doğrudur:

false, 0, -0, 0n, "", null, undefined, NaN     ← yanlış (falsy)

// Doğru sayılanlar arasında ŞUNLAR DA VAR — sık şaşırtır:
[]        // boş dizi   → doğru
{}        // boş nesne  → doğru
"0"       // "0" dizesi → doğru
"false"   //            → doğru

Boş bir diziyi if (liste) ile kontrol etmek her zaman doğru döner; doğrusu if (liste.length)'tir.

||, ??, ?.

const adet1 = girdi || 10;    // girdi YANLIŞ sayılan her şeyse 10 → 0 ve "" de kaçar!
const adet2 = girdi ?? 10;    // yalnız null/undefined ise 10 → 0 korunur

ayarlar.sayfa ??= 1;          // yoksa ata (birleşik atama)

kullanici?.adres?.sehir       // ara değer null/undefined ise undefined döner, hata fırlatmaz
kullanici.kaydet?.()          // metot varsa çağır
liste?.[0]

|| ile ?? farkı gerçek hata üretir: kullanıcı bir sayı alanına 0 yazdığında girdi || 10 onu 10 yapar; sıfır geçerli bir değerdir ve sessizce kaybolur. Varsayılan değer verirken ?? kullan.

?.'in sınırı: yalnız null ve undefined'ı korur. Hatanın kaynağını gizleyebildiği için zincirin tamamına serpiştirmek iyi bir fikir değildir — veri gerçekten isteğe bağlıysa kullan, "olmalıydı ama yok" durumunda hata görmek daha iyidir.

08Koşullar ve döngüler

if (puan >= 85)      { durum = "yüksek"; }
else if (puan >= 50) { durum = "geçer"; }
else                 { durum = "yetersiz"; }

const etiket = puan >= 50 ? "geçti" : "kaldı";     // üçlü operatör

switch (tur) {
  case "yeni":
  case "yenileme":            // birleşik durum — bilinçli düşme
    islet();
    break;                    // BREAK UNUTULURSA sonraki case'e DÜŞER
  default:
    hata();
}

switch'in iki tuzağı: (1) break unutmak sessizce sonraki bloğu da çalıştırır; (2) karşılaştırma === iledir — switch("1") ile case 1: eşleşmez. Ayrıca case içinde let/const bildirmek için blok parantezi gerekir (case "x": { const a = 1; break; }).

DöngüNe üzerindeNe zaman
for (let i = 0; …)Sayaçİndekse ihtiyaç varsa, geriye doğru gidilecekse
for...ofDeğerlerDizi ve yinelenebilirler için varsayılan tercih; break çalışır
for...inAnahtarlarNesne özellikleri — dizide kullanma
while / do...whileKoşulYineleme sayısı bilinmiyorsa
forEachDeğerlerOkunaklı, ama break ve await çalışmaz
const notlar = [70, 85, 92];

for (const n of notlar) { if (n > 90) break; }        // değer
for (const i in notlar) { console.log(i); }            // "0","1","2" — DİZE anahtar!
notlar.forEach((n, i) => console.log(i, n));
for (const [i, n] of notlar.entries()) { }             // hem indeks hem değer

for...in neden dizide kullanılmaz: anahtarları dize olarak verir, sırayı garanti etmez ve kalıtılan özellikleri de dolaşır. Nesne dolaşmak istiyorsan modern karşılığı Object.keys/values/entries ile for...of'tur.

for (const [anahtar, deger] of Object.entries(nesne)) { … }

forEach'in iki sınırı pratikte önemlidir: içinde break kullanılamaz (erken çıkmak için some/find gerekir) ve await beklenmez — asenkron işlemde döngü bitmeden ilerlenir. 17. derste göreceğin bu tuzak, "veriler eksik geliyor" hatalarının klasik kaynağıdır.

09Sıkı mod ve savunma alışkanlıkları

"use strict";     // dosya ya da fonksiyon başında

x = 5;            // sıkı modda ReferenceError — sıkı mod olmadan KÜRESEL değişken yaratırdı

Sıkı mod, dilin bazı sessiz hatalarını gerçek hataya çevirir: bildirilmemiş değişkene atama, salt okunur özelliğe yazma, aynı ada sahip iki parametre. ES modülleri (type="module") ve sınıflar zaten sıkı moddadır; yani modern kodda ayrıca yazmana genelde gerek kalmaz.

Bilinmesi gereken son davranış otomatik noktalı virgül eklemedir: JavaScript satır sonlarına noktalı virgülü kendisi ekler, ama birkaç durumda yanlış yerde ekler:

return
  { ad: "Ayşe" };     // undefined döner! return'den sonra satır sonu → noktalı virgül eklenir

Bu yüzden return ile değeri aynı satıra yaz. Genel olarak biçimlendirmeyi elle tartışmak yerine bir biçimlendiriciye bırakmak (editörde kaydederken otomatik biçimlendirme) ve statik bir denetleyici kullanmak yaygın ekip pratiğidir; ikisi de bu dersteki tuzakların çoğunu yazarken yakalar. Tipleri derleme anında yakalayan çözüm ise 9. hattın konusu olan TypeScript'tir — bu hattaki tuzakların büyük kısmının var oluş sebebi odur.

10Mini alıştırma — Tuzakları konsolda gör

Yaklaşık 20 dakika · yalnız tarayıcı konsolu (F12), dosya bile gerekmez

  1. Kapsam: var ve let ile birer döngü yazıp içine setTimeout(() => console.log(i), 0) koy. Çıktılar neden farklı?
  2. Ölü bölge: bildirimden önce bir var ve bir let değişkenini yazdır. Hangisi hata verdi, hangisi undefined?
  3. const: bir const nesnenin özelliğini değiştir, sonra nesnenin kendisini yeniden ata. Hangisi hata verdi? Object.freeze ekleyip iç içe bir nesneyi değiştirmeyi dene.
  4. typeof: null, [], {}, bir fonksiyon ve NaN için typeof sonuçlarını yazdır. Kaç tanesi beklediğin gibi?
  5. Sayı: 0.1 + 0.2, 0.1 + 0.2 === 0.3 ve (0.1 + 0.2).toFixed(2) yazdır. Sonuncusunun tipi ne?
  6. Güvenli sınır: Number.MAX_SAFE_INTEGER + 1 ve + 2 sonuçlarını karşılaştır.
  7. NaN: NaN === NaN ve Number.isNaN(NaN) sonuçlarını gör. isNaN("abc") ile Number.isNaN("abc") neden farklı?
  8. Sıralama: [10, 1, 2].sort() çalıştır. Sonuç neden yanlış? Karşılaştırma fonksiyonu ekleyip düzelt.
  9. Türkçe: "IŞIK".toLowerCase() ve "IŞIK".toLocaleLowerCase("tr") sonuçlarını karşılaştır. Bir kullanıcı adı eşleştirmesinde bu fark neye yol açar?
  10. Dönüşüm: "5" + 3, "5" - 3, [] + {}, [] == false yazdır. Hangi kural işledi?
  11. Doğruluk değeri: if ([]), if ("0"), if (0), if ("") testlerini yaz. Boş bir listeyi kontrol etmenin doğru yolu ne?
  12. || vs ??: const adet = 0 için ikisini de dene. Hangisi sıfırı korudu?
  13. Zincir: derin bir nesnede olmayan bir alana önce doğrudan, sonra ?. ile eriş.
  14. switch: bir break'i bilerek sil ve düşmeyi gözle. Sonra switch("1") ile case 1: eşleşiyor mu bak.
  15. Döngü: aynı diziyi for...of, for...in ve forEach ile dolaş. for...in'in verdiği anahtarların tipi ne? forEach içinde break yazmayı dene.
  16. Sıkı mod: konsola önce y = 5, sonra "use strict"; z = 5 yaz (ikincisini bir fonksiyon içinde). Fark ne?

11Kendini sına

var, let ve const arasındaki farklar nelerdir?

Kapsam: var fonksiyon kapsamlıdır — bir if ya da for bloğu içinde bildirilse bile tüm fonksiyonda görünür; let ve const blok kapsamlıdır. Yeniden atama: const yeniden atanamaz, diğer ikisi atanabilir. Yukarı kaldırma: üçü de kaldırılır, ama var bildirimden önce undefined değeriyle erişilebilir (hatayı gizler), let ve const geçici ölü bölgede durur ve erişim ReferenceError fırlatır (hatayı gösterir). Küresel nesne: küresel kapsamdaki var window'a özellik ekler, diğerleri eklemez. Klasik örnek: var'lı bir döngüde setTimeout ile indeks yazdırırsan hep son değeri (3, 3, 3) görürsün — tek bir değişken vardır; let ile her yineleme kendi bağlamasını alır (0, 1, 2). Son olarak const yalnız bağlamayı sabitler: nesnenin içeriği değiştirilebilir (kullanici.ad = "..." geçerlidir), bunu da engellemek için Object.freeze gerekir ve o da yüzeyseldir. Pratik: her şeye const ile başla, gerekince let'e çevir, var kullanma.

== ile === farkı nedir? Hangisini kullanırsın?

=== katı eşitliktir: önce tipe bakar, tipler farklıysa doğrudan false döner. == gevşek eşitliktir: tipler farklıysa otomatik dönüşüm yapıp karşılaştırır ve bu, sezgiye aykırı sonuçlar üretir — 0 == false, "" == 0, "1" == 1, [] == false hepsi true'dur. Dönüşüm kuralları karmaşıktır ve ezberlenmez; kaçınılır. Kural: her zaman === (ve !==) kullan. Tek yaygın kabul gören istisna x == null'dır: bu tek yazım hem null hem undefined'ı yakalar ve x === null || x === undefined yazmaktan kısadır. İki ek not: NaN hiçbir şeye, kendisine bile eşit değildir — kontrol Number.isNaN() ile yapılır. Ve nesneler referansa göre karşılaştırılır: {a:1} === {a:1} false'tur; içerik karşılaştırması için elle dolaşmak ya da bir yardımcı kullanmak gerekir.

0.1 + 0.2 === 0.3 neden false? Para tutarlarını nasıl saklarsın?

JavaScript'te tek bir sayı tipi vardır ve IEEE 754 çift duyarlıklı kayan noktadır. 0.1 ve 0.2 ikilik tabanda tam olarak temsil edilemez (tıpkı 1/3'ün onluk tabanda 0,333… olması gibi); toplam 0.30000000000000004 çıkar. Bu JavaScript'e özgü bir kusur değildir, ikili kayan noktalı her dilde aynıdır. Sonuçlar: eşitlik karşılaştırması yapılmaz — gerekiyorsa Math.abs(a - b) < Number.EPSILON gibi bir tolerans kullanılır; toFixed() dize döndürür, sayı değil. Para için iki doğru yol vardır: (1) tutarı en küçük birimde tam sayı tutmak (kuruş: 19,90 TL → 1990) ve yalnız gösterirken bölmek — güvenli tam sayı sınırı (Number.MAX_SAFE_INTEGER, ~9·10¹⁵) aşılmadığı sürece kesindir; (2) ondalık aritmetik kütüphanesi kullanmak. Çok büyük tam sayılar için BigInt vardır ama ondalık çözmez. Sunucu ve veritabanı tarafında karşılığı C#'ta decimal, SQL'de DECIMAL/NUMERIC'tir. Gösterimde elle nokta-virgül değiştirmek yerine Intl.NumberFormat("tr-TR", …) kullanılır.

|| ile ?? arasındaki fark nedir? Hangi durumda gerçek hata üretir?

|| sol taraf yanlış sayılan (falsy) herhangi bir değerse sağ tarafı döndürür. Yanlış sayılan değerler: false, 0, -0, 0n, "", null, undefined, NaN. ?? (boş değer birleştirme) ise yalnız null ve undefined için sağ tarafı döndürür. Gerçek hata şurada çıkar: kullanıcı bir sayı alanına 0 yazdığında ya da bir metin alanını bilerek boş bıraktığında, const adet = girdi || 10 bu geçerli değerleri varsayılanla değiştirir — sıfır adet sipariş 10 adede döner, boş bırakılan açıklama varsayılan metne. Aynı durum false için de geçerlidir: bir ayarın kapalı olması ayar || true ile sessizce açık hâle gelir. Kural: varsayılan değer verirken ??, mantıksal "veya" gerektiğinde ||. Aynı aileden ??= ("yoksa ata") ve ?. (isteğe bağlı zincir) vardır; ?. de yalnız null/undefined'ı korur ve her yere serpiştirilmesi hatanın kaynağını gizlediği için önerilmez.

12Sınav köşesi

Yazılıda nasıl sorulur

(1) var, let, const farkı — en klasik soru. (2) Hoisting nedir? (3) JavaScript'teki veri tiplerini sayınız; ilkel ve referans tip farkı. (4) null ile undefined farkı. (5) == ile === farkı. (6) Falsy değerleri yazınız. (7) typeof null ne döner, neden? (8) NaN nedir, nasıl kontrol edilir? (9) for...in ile for...of farkı. (10) switch içinde break unutulursa ne olur? (11) Şablon değişmezleri (template literal). (12) 0.1 + 0.2 neden 0.3 değildir? (13) Strict mode nedir?

Sözlüde nasıl anlatılır — 2 dakikalık taslak

Düzen: (1) Dil — "JavaScript dinamik tipli, yorumlanan bir dildir; tarayıcıda ve Node.js'te aynı motor çalışır. Dilin kendisiyle tarayıcı arayüzlerini (DOM, fetch) ayrı tutarım." (2) Değişkenler — "her şeyi const ile başlatır, gerekince let'e çeviririm; var fonksiyon kapsamlı olduğu ve bildirimden önce undefined döndürerek hatayı gizlediği için kullanmam." (3) Kıdem vuruşu — "dilin en büyük riski otomatik tip dönüşümüdür; bu yüzden her zaman === kullanırım. Varsayılan değer verirken || değil ?? yazarım — aksi hâlde kullanıcının girdiği 0 ya da boş dize sessizce varsayılana dönüşür." (4) Sayı ve yerelleştirme — "tek sayı tipi kayan noktadır; para tutarını kuruş cinsinden tam sayı tutar, gösterimi Intl.NumberFormat ile yaparım. Türkçe metinlerde toLowerCase yerine toLocaleLowerCase('tr') kullanırım, yoksa 'I' harfi yanlış dönüşür." (5) Süreç — "tuzakların çoğunu yazarken yakalamak için biçimlendirici ve statik denetleyici kullanırım; asıl çözüm ise tipleri derleme anında kontrol eden TypeScript'tir."