Operatörler ve Tip Dönüşümleri
Giriş — Operatörler: Dilin Fiilleri
Eğer değişkenler programlamanın "isimleri" ise, operatörler programlamanın "fiilleri"dir. Topla, karşılaştır, ata, birleştir, kontrol et — tüm bu eylemleri operatörlerle yaparız. Bir hesap makinesi düşünün: sayılar tek başına bir anlam ifade etmez, ama aralarına +, -, × koyduğunuz anda anlam kazanırlar.
JavaScript'in operatörleri ilk bakışta basit görünür, ama yüzeyin altında type coercion (otomatik tip dönüşümü) adlı bir mekanizma çalışır. Bu mekanizma, bazen hayat kurtarır, bazen de "Bu nasıl oldu?" dedirten sürprizler yaratır. Bu derste tüm operatör ailelerini öğrenecek, == ile === arasındaki kritik farkı kavrayacak ve JavaScript'in truthy/falsy dünyasını keşfedeceksiniz.
Analoji: Type coercion, bir tercüman gibi çalışır. Siz Türkçe konuşursunuz, karşınızdaki İngilizce. JavaScript araya girip "Ben çevireyim" der ve iki farklı tipi aynı dile çevirir. Ama bazen bu çeviriler beklenmedik sonuçlar doğurur — "evet" derken karşı taraf "hayır" anlar.
Aritmetik Operatörler
Matematiksel işlemler için kullanılır. Çoğu beklediğiniz gibi çalışır, ama + operatörünün çift kişiliği vardır — hem toplama hem string birleştirme yapar.
Temel Aritmetik
let a = 10;
let b = 3;
console.log(a + b); // 13 — Toplama
console.log(a - b); // 7 — Çıkarma
console.log(a * b); // 30 — Çarpma
console.log(a / b); // 3.3333... — Bölme (her zaman ondalık!)
console.log(a % b); // 1 — Mod (kalan): 10 / 3 = 3, kalan 1
console.log(a ** b); // 1000 — Üs alma: 10³ (ES2016)Mod operatörünün (`%`) pratik kullanımları:
// Çift/tek kontrolü
let sayi = 7;
console.log(sayi % 2 === 0 ? "Çift" : "Tek"); // "Tek"
// Belirli aralıkta döngü (circular index)
// Örn: 7 günlük haftada 10. gün hangi gün?
const gunler = ["Pzt", "Sal", "Çar", "Per", "Cum", "Cmt", "Paz"];
let gunIndex = 10 % 7; // 3
console.log(gunler[gunIndex]); // "Per"
// Her n'inci elemanda işlem yapma
for (let i = 1; i <= 20; i++) {
if (i % 5 === 0) {
console.log(`${i} → 5'in katı!`);
}
}Artırma ve Azaltma (Increment / Decrement)
let sayac = 5;
// Postfix — önce mevcut değeri kullan, sonra artır
console.log(sayac++); // 5 (önce 5'i gösterir)
console.log(sayac); // 6 (şimdi artmış)
// Prefix — önce artır, sonra kullan
console.log(++sayac); // 7 (önce artırır, sonra gösterir)
// Azaltma da aynı mantıkla çalışır
console.log(sayac--); // 7 (önce gösterir)
console.log(sayac); // 6 (şimdi azalmış)
console.log(--sayac); // 5 (önce azaltır)⚠️ Dikkat: ++ ve -- operatörlerini karmaşık ifadelerin içinde kullanmayın — kodun okunabilirliğini düşürür ve beklenmedik sonuçlar doğurabilir. sayac++ yerine sayac += 1 yazmak genellikle daha açıktır (döngüler hariç).
+ Operatörünün Çift Kişiliği
+ operatörü, operand'lardan biri string ise birleştirme, ikisi de sayı ise toplama yapar. Bu, JavaScript'teki en yaygın kafa karışıklıklarından biridir:
// Toplama (iki taraf da number)
console.log(5 + 3); // 8
// Birleştirme (en az bir taraf string)
console.log("5" + 3); // "53" — 3 string'e dönüştürülür
console.log(5 + "3"); // "53" — 5 string'e dönüştürülür
console.log("Merhaba" + " " + "Dünya"); // "Merhaba Dünya"
// Tuzak — soldan sağa değerlendirme
console.log(1 + 2 + "3"); // "33" — önce 1+2=3, sonra 3+"3"="33"
console.log("1" + 2 + 3); // "123" — "1"+2="12", "12"+3="123"// ❌ Yaygın hata — form'dan gelen değer her zaman string'dir
let inputDeger = "100"; // Kullanıcıdan gelen input
let kdv = 18;
console.log(inputDeger + kdv); // "10018" — String birleştirme!
// ✅ Çözüm — önce number'a dönüştürün
console.log(Number(inputDeger) + kdv); // 118
console.log(+inputDeger + kdv); // 118 (unary plus)
console.log(parseInt(inputDeger) + kdv); // 118Atama Operatörleri
Değişkenlere değer atamak ve mevcut değer üzerinde işlem yapmak için kullanılır:
let x = 10; // Temel atama
// Bileşik atama operatörleri
x += 5; // x = x + 5 → 15
x -= 3; // x = x - 3 → 12
x *= 2; // x = x * 2 → 24
x /= 4; // x = x / 4 → 6
x %= 4; // x = x % 4 → 2
x **= 3; // x = x ** 3 → 8
// String ile += kullanımı
let mesaj = "Merhaba";
mesaj += ", ";
mesaj += "Dünya!";
console.log(mesaj); // "Merhaba, Dünya!"Mantıksal Atama Operatörleri (ES2021)
Bu operatörler nispeten yenidir ama çok kullanışlıdır:
// ||= (Logical OR assignment) — falsy ise ata
let kullaniciAdi = "";
kullaniciAdi ||= "Anonim";
console.log(kullaniciAdi); // "Anonim" — boş string falsy olduğu için
// &&= (Logical AND assignment) — truthy ise ata
let config = { debug: true };
config.debug &&= false; // debug truthy olduğu için false atanır
console.log(config.debug); // false
// ??= (Nullish coalescing assignment) — null veya undefined ise ata
let port = null;
port ??= 3000;
console.log(port); // 3000
let timeout = 0;
timeout ??= 5000;
console.log(timeout); // 0 — 0 null/undefined DEĞİLDİR, atama yapılmaz!💡 İpucu: ??= ile ||= arasındaki fark kritiktir. ||= tüm falsy değerlerde (0, "", false, null, undefined) atar. ??= sadece null ve undefined'da atar. 0 veya "" geçerli bir değerse ??= kullanın.
Karşılaştırma Operatörleri
İki değeri karşılaştırır ve true veya false döner. Ama JavaScript'te karşılaştırma, sandığınız kadar basit değildir.
Temel Karşılaştırma
console.log(5 > 3); // true — büyüktür
console.log(5 < 3); // false — küçüktür
console.log(5 >= 5); // true — büyük eşit
console.log(5 <= 4); // false — küçük eşit== vs === — JavaScript'in En Önemli Farkı
Bu, JavaScript'te en çok kafa karıştıran ve en çok hata yapılan konulardan biridir. İki eşitlik operatörü arasındaki farkı derinlemesine anlayalım.
`==` (Gevşek Eşitlik — Abstract Equality)
Karşılaştırma yapmadan önce, iki tarafı aynı tipe dönüştürmeye çalışır. Bu dönüşüme type coercion denir:
// == tip dönüşümü yapar
console.log(5 == "5"); // true — "5" → 5'e dönüştürülür
console.log(0 == false); // true — false → 0'a dönüştürülür
console.log("" == false); // true — "" → 0, false → 0
console.log(null == undefined); // true — özel kural
console.log(1 == true); // true — true → 1'e dönüştürülür
// Tuzaklı sonuçlar
console.log("" == 0); // true
console.log("0" == false); // true
console.log("" == false); // true
// Ama:
console.log("" == "0"); // false — ikisi de string, dönüşüm yok`===` (Sıkı Eşitlik — Strict Equality)
Tip dönüşümü yapmaz. Hem tipi hem değeri kontrol eder:
// === tip dönüşümü YAPMAZ
console.log(5 === "5"); // false — number !== string
console.log(0 === false); // false — number !== boolean
console.log("" === false); // false — string !== boolean
console.log(null === undefined); // false — farklı tipler
console.log(1 === true); // false — number !== boolean
// Aynı tip ve aynı değer olmalı
console.log(5 === 5); // true
console.log("abc" === "abc"); // trueAnaloji:
==soran bir görevli gibidir: "Bu iki şey benzer mi?" — rengine, şekline bakar, yaklaştırır. 5 ile "5" arasında "eh, ikisi de 5'i ifade ediyor" der.===ise titiz bir kontrol görevlisidir: "Bu iki şey birebir aynı mı?" — tipine, değerine, her şeyine bakar. 5 (number) ile "5" (string) arasında "hayır, biri sayı biri metin" der.
⚠️ Dikkat: Her zaman `===` kullanın. =='nin tip dönüşümü kuralları karmaşık ve hataya açıktır. Tek istisna: value == null kontrolü, hem null hem undefined'ı yakalar ve bu kullanım bazı style guide'larda kabul edilir. Bunun dışında === kullanın.
// ❌ == ile beklenmedik sonuçlar
if (userInput == 0) {
// userInput "" (boş string) olsa bile buraya girer!
// Çünkü "" == 0 → true
}
// ✅ === ile güvenli kontrol
if (userInput === 0) {
// Sadece gerçekten 0 ise girer
}!= vs !==
Eşitsizlik operatörleri de aynı mantıkla çalışır:
console.log(5 != "5"); // false — == ile true olduğu için, != false
console.log(5 !== "5"); // true — === ile false olduğu için, !== true
// Her zaman !== kullanınMantıksal Operatörler
Mantıksal operatörler (&&, ||, !) koşulları birleştirmek ve kontrol etmek için kullanılır. Ama JavaScript'te bu operatörler sadece true/false döndürmez — çok daha akıllı çalışırlar.
&& (VE — AND)
Her iki taraf da true ise true döner:
// Temel mantıksal kullanım
let yas = 25;
let ehliyet = true;
if (yas >= 18 && ehliyet) {
console.log("Araba kullanabilir");
}
// Kısa devre değerlendirme (short-circuit evaluation)
// && ilk falsy değeri DÖNDÜRÜR, hepsi truthy ise son değeri döndürür
console.log("Ali" && "Veli"); // "Veli" — ikisi de truthy, sonu döner
console.log("" && "Veli"); // "" — ilk falsy'de durur
console.log(null && "Veli"); // null
console.log(1 && 2 && 3); // 3 — hepsi truthy, son değer
console.log(1 && 0 && 3); // 0 — ilk falsy değerPratik kullanım — koşullu çalıştırma:
// && ile kısa if-else
let kullanici = { isim: "Ali", admin: true };
// Eğer admin ise mesajı göster
kullanici.admin && console.log("Admin paneline hoş geldin!");
// Güvenli property erişimi (optional chaining öncesi)
let adres = kullanici && kullanici.adres && kullanici.adres.sehir;
// Modern yol:
let adres2 = kullanici?.adres?.sehir; // Optional chaining (ES2020)|| (VEYA — OR)
En az bir taraf true ise true döner:
let gun = "Cumartesi";
if (gun === "Cumartesi" || gun === "Pazar") {
console.log("Hafta sonu!");
}
// Kısa devre — ilk truthy değeri döndürür
console.log("" || "varsayılan"); // "varsayılan"
console.log(null || "varsayılan"); // "varsayılan"
console.log(undefined || "varsayılan"); // "varsayılan"
console.log(0 || 42); // 42
console.log("Ali" || "varsayılan"); // "Ali" — zaten truthy
// Varsayılan değer atama — klasik pattern
let kullaniciAdi = inputDeger || "Anonim";?? (Nullish Coalescing — ES2020)
|| ile benzerdir ama sadece null ve undefined için çalışır:
// || ile sorun
let miktar = 0;
console.log(miktar || 100); // 100 — 0 falsy olduğu için!
// Ama 0 geçerli bir miktar olabilir!
// ?? ile çözüm
console.log(miktar ?? 100); // 0 — 0 null/undefined değil, kendi değerini döndürür
console.log(null ?? 100); // 100 — null ise varsayılan
console.log(undefined ?? 100); // 100 — undefined ise varsayılan
// Gerçek hayat örneği
function ayarlariYukle(config) {
let port = config.port ?? 3000; // 0 olabilir, sorun yok
let debug = config.debug ?? false; // false geçerli bir değer
let timeout = config.timeout ?? 5000; // 0 ms olabilir
return { port, debug, timeout };
}
console.log(ayarlariYukle({ port: 0, debug: false }));
// { port: 0, debug: false, timeout: 5000 }
// || kullanılsaydı: { port: 3000, debug: false, timeout: 5000 } — YANLIŞ!💡 İpucu: Varsayılan değer atarken: "0, '' (boş string) veya false geçerli bir değer olabilir mi?" sorusunu sorun. Cevap evet ise ??, hayır ise || kullanın. Şüphedeyseniz ?? daha güvenlidir.
! (DEĞİL — NOT)
Değerin boolean karşıtını döndürür:
console.log(!true); // false
console.log(!false); // true
console.log(!"Ali"); // false (truthy → false)
console.log(!""); // true (falsy → true)
console.log(!0); // true
console.log(!null); // true
// Çift ünlem (!!) — herhangi bir değeri boolean'a dönüştürür
console.log(!!"Ali"); // true
console.log(!!0); // false
console.log(!!null); // false
console.log(!![]); // true — boş dizi truthy!
console.log(!!{}); // true — boş nesne truthy!
// Boolean() ile aynı sonucu verir, ama !! daha kısa
console.log(Boolean("Ali")); // trueTruthy ve Falsy Değerler
JavaScript'te her değer bir boolean bağlamda kullanıldığında true veya false olarak değerlendirilir. Bu kavram, koşullu ifadelerde (if, while, ternary) sürekli karşınıza çıkar.
Falsy Değerler — Tam Liste (Ezbere Bilin!)
JavaScript'te sadece 8 falsy değer vardır. Geriye kalan her şey truthy'dir:
// Tüm falsy değerler
console.log(Boolean(false)); // false
console.log(Boolean(0)); // false
console.log(Boolean(-0)); // false
console.log(Boolean(0n)); // false (BigInt sıfır)
console.log(Boolean("")); // false (boş string)
console.log(Boolean(null)); // false
console.log(Boolean(undefined)); // false
console.log(Boolean(NaN)); // false
// Bu 8 değer dışında HER ŞEY truthy'dir!Şaşırtıcı Truthy Değerler
// Bunlar truthy'dir — çoğu insanı şaşırtır
console.log(Boolean([])); // true — boş dizi!
console.log(Boolean({})); // true — boş nesne!
console.log(Boolean("0")); // true — "0" string'i (boş değil!)
console.log(Boolean("false")); // true — "false" string'i
console.log(Boolean(-1)); // true — negatif sayı
console.log(Boolean(Infinity)); // true — sonsuz
console.log(Boolean(new Date())); // true — Date objesi
console.log(Boolean(function(){})); // true — fonksiyon
// EN BÜYÜK TUZAK:
console.log([] == false); // true — ama Boolean([]) true'dur!
// Neden? == coercion kuralları farklı çalışır:
// [] → "" → 0, false → 0, 0 == 0 → true⚠️ Dikkat: [] == false true döner ama [] truthy'dir. Bu tutarsızlık == operatörünün coercion kurallarından kaynaklanır. Bu, === kullanmanız gerektiğinin en güçlü kanıtlarından biridir.
Truthy/Falsy'nin Pratik Kullanımı
// Değer var mı kontrolü
let isim = "";
// ❌ Gereksiz karşılaştırma
if (isim !== "" && isim !== null && isim !== undefined) {
console.log("İsim var");
}
// ✅ Truthy kontrolü — daha kısa ve okunabilir
if (isim) {
console.log("İsim var");
} else {
console.log("İsim boş veya tanımsız");
}
// Dizi boş mu kontrolü
let urunler = [];
// ❌ Yanlış! Boş dizi truthy'dir
if (urunler) {
console.log("Ürünler var"); // Her zaman buraya girer — boş dizi bile truthy!
}
// ✅ Doğru — length kontrolü
if (urunler.length > 0) {
console.log("Ürünler var");
}
// Veya kısaca (length 0 ise falsy):
if (urunler.length) {
console.log("Ürünler var");
}Ternary (Üçlü) Operatör
if/else'in tek satırlık versiyonudur. koşul ? doğruysa : yanlışsa şeklinde yazılır:
// if/else versiyonu
let yas = 20;
let durum;
if (yas >= 18) {
durum = "Yetişkin";
} else {
durum = "Çocuk";
}
// Ternary versiyonu — aynı iş, tek satır
let durum2 = yas >= 18 ? "Yetişkin" : "Çocuk";
console.log(durum2); // "Yetişkin"
// Template literal içinde kullanımı
console.log(`Kullanıcı ${yas >= 18 ? "yetişkin" : "reşit değil"}`);
// İç içe ternary — okunabilirliğe DİKKAT
let puan = 85;
let harf = puan >= 90 ? "A"
: puan >= 80 ? "B"
: puan >= 70 ? "C"
: puan >= 60 ? "D"
: "F";
console.log(harf); // "B"⚠️ Dikkat: İç içe (nested) ternary operatörler okunabilirliği ciddi şekilde düşürür. İkiden fazla koşul varsa, if/else veya switch kullanın. Tek koşullu basit ternary'ler mükemmeldir; karmaşık olanlar bakım kabusudur.
Type Coercion Derinlemesine
JavaScript'in otomatik tip dönüşüm kurallarını anlamak, beklenmedik hatalardan kaçınmak için şarttır.
Coercion Kuralları
// String dönüşümü (+ operatörü ile)
console.log(1 + "2"); // "12" — number → string
console.log(true + "test"); // "truetest" — boolean → string
console.log(null + "test"); // "nulltest"
console.log(undefined + "test"); // "undefinedtest"
// Number dönüşümü (-, *, /, % operatörleri ile)
console.log("6" - 2); // 4 — string → number
console.log("6" * "2"); // 12
console.log(true + 1); // 2 — true → 1
console.log(false + 1); // 1 — false → 0
console.log(null + 1); // 1 — null → 0
console.log(undefined + 1); // NaN — undefined → NaN
// Boolean dönüşümü (mantıksal bağlam)
if ("merhaba") { } // "merhaba" → true
if (0) { } // 0 → false
if ([]) { } // [] → true (boş dizi truthy!)Coercion Tuzakları — Kapsamlı Örnekler
// Her birinin neden o sonucu verdiğini anlayın
console.log([] + []); // "" — ikisi de string'e dönüşür: "" + "" = ""
console.log([] + {}); // "[object Object]" — "" + "[object Object]"
console.log({} + []); // 0 (bazı ortamlarda) veya "[object Object]"
console.log(true + true); // 2 — 1 + 1
console.log(true + false); // 1 — 1 + 0
console.log("5" - - "3"); // 8 — 5 - (-3) = 8
console.log("foo" + + "bar"); // "fooNaN" — +"bar" = NaN, "foo" + NaN = "fooNaN"
// == ile coercion tuzakları
console.log(false == ""); // true — ikisi de 0'a dönüşür
console.log(false == []); // true — [] → "" → 0, false → 0
console.log(false == {}); // false — {} → NaN
console.log("" == 0); // true — "" → 0
console.log("" == []); // true — [] → ""
console.log(0 == []); // true — [] → "" → 0
// === ile hiçbir sürpriz yok
console.log(false === ""); // false — farklı tipler
console.log(false === []); // false — farklı tipler
console.log("" === 0); // false — farklı tiplerCoercion'dan Kaçınma Stratejileri
// 1. Her zaman === ve !== kullanın
if (value === 0) { /* ... */ }
// 2. Açık tip dönüşümü yapın
let input = "42";
let sayi = Number(input); // Bilinçli dönüşüm
// 3. Unary plus (+) ile number'a dönüştürün
let fiyat = +"99.99"; // 99.99
// 4. Boolean bağlamda !! kullanın
let varMi = !!deger;
// 5. Template literal kullanın (+ ile birleştirme yerine)
let mesaj = `Sonuç: ${sayi}`; // + kullanmadanString Operatörleri
Birleştirme (Concatenation)
// + ile birleştirme (eski yöntem)
let ad = "Ali";
let soyad = "Yılmaz";
let tamIsim = ad + " " + soyad;
console.log(tamIsim); // "Ali Yılmaz"
// Template literal ile (modern ve önerilen yöntem)
let tamIsim2 = `${ad} ${soyad}`;
console.log(tamIsim2); // "Ali Yılmaz"
// Çok satırlı string
let html = `
<div class="card">
<h2>${tamIsim}</h2>
<p>Hoş geldiniz!</p>
</div>
`;String Karşılaştırma
// Stringler Unicode değerlerine göre karşılaştırılır
console.log("a" < "b"); // true — 'a' (97) < 'b' (98)
console.log("Z" < "a"); // true — 'Z' (90) < 'a' (97) — büyük harfler önce!
console.log("10" < "9"); // true — string olarak: '1' (49) < '9' (57)!
// Sayısal karşılaştırma için number'a dönüştürün
console.log(Number("10") < Number("9")); // false — doğru sonuçOperatör Önceliği (Operator Precedence)
Matematikteki işlem sırası gibi, JavaScript'te de operatörlerin bir öncelik sırası vardır:
// Çarpma, toplama'dan önce gelir
console.log(2 + 3 * 4); // 14 — 3*4=12, 2+12=14 (12 değil!)
console.log((2 + 3) * 4); // 20 — parantez önceliği değiştirir
// Mantıksal operatörlerde: ! > && > ||
let sonuc = true || false && false;
console.log(sonuc); // true — && önce: false && false = false, true || false = true
// Karmaşık ifadelerde PARANTEZ KULLANIN
let sonuc2 = (true || false) && false;
console.log(sonuc2); // false — parantezle anlam değişti
// Öncelik sırası (yüksekten düşüğe, özet)
// 1. () — Parantez (gruplama)
// 2. !, ++, --, typeof — Tekli (unary) operatörler
// 3. ** — Üs alma
// 4. *, /, % — Çarpma, bölme, mod
// 5. +, - — Toplama, çıkarma
// 6. <, >, <=, >= — Karşılaştırma
// 7. ==, ===, !=, !== — Eşitlik
// 8. && — Mantıksal VE
// 9. || — Mantıksal VEYA
// 10. ?? — Nullish coalescing
// 11. = — Atama💡 İpucu: Operatör önceliğini ezberlemeye çalışmayın. Kafanızda şüphe varsa parantez kullanın. Parantez hem doğru sonucu garanti eder hem de kodu okuyan kişinin niyetinizi anlamasını sağlar.
Optional Chaining (?.) — ES2020
Derin nesne yapılarında güvenli erişim sağlar. Bir özellik null veya undefined ise hata fırlatmak yerine undefined döner:
let kullanici = {
isim: "Ali",
adres: {
sehir: "İstanbul",
ilce: "Kadıköy"
}
};
// ❌ Eski yöntem — uzun ve çirkin
let sehir;
if (kullanici && kullanici.adres && kullanici.adres.sehir) {
sehir = kullanici.adres.sehir;
}
// ✅ Modern yol — optional chaining
let sehir2 = kullanici?.adres?.sehir;
console.log(sehir2); // "İstanbul"
// Yoksa undefined döner — hata fırlatmaz
let ulke = kullanici?.adres?.ulke;
console.log(ulke); // undefined (hata yok!)
// ?? ile birleştirerek varsayılan değer
let ulke2 = kullanici?.adres?.ulke ?? "Türkiye";
console.log(ulke2); // "Türkiye"
// Metot çağrısında
let kullanici2 = null;
console.log(kullanici2?.isim?.toUpperCase()); // undefined — hata yok
// Dizi erişiminde
let dizi = null;
console.log(dizi?.[0]); // undefined — hata yok
// Fonksiyon çağrısında
let fonksiyon = null;
console.log(fonksiyon?.()); // undefined — hata yokGerçek Dünya Örneği: Fiyat Hesaplayıcı
Tüm operatörleri birleştiren kapsamlı bir örnek:
// E-ticaret fiyat hesaplayıcı
function fiyatHesapla(urun) {
// Güvenli erişim (optional chaining + nullish coalescing)
const birimFiyat = urun?.fiyat ?? 0;
const adet = urun?.adet ?? 1;
const indirimYuzde = urun?.indirim ?? 0;
const kdvOrani = urun?.kdv ?? 18;
const kargoBedeli = urun?.kargoUcretsiz ? 0 : (urun?.kargo ?? 29.99);
// Hesaplamalar
const araToplam = birimFiyat * adet;
const indirimTutar = araToplam * (indirimYuzde / 100);
const indirimliToplam = araToplam - indirimTutar;
const kdvTutar = indirimliToplam * (kdvOrani / 100);
const genelToplam = indirimliToplam + kdvTutar + kargoBedeli;
// Sonuçları formatla
const formatla = (sayi) => sayi.toFixed(2) + " TL";
return `
╔═══════════════════════════════════╗
║ FATURA ║
╠═══════════════════════════════════╣
║ Ürün: ${(urun?.isim ?? "Bilinmeyen").padEnd(25)}║
║ Birim Fiyat: ${formatla(birimFiyat).padStart(18)} ║
║ Adet: ${String(adet).padStart(25)} ║
║ Ara Toplam: ${formatla(araToplam).padStart(19)} ║
${indirimYuzde > 0 ? `║ İndirim (%${indirimYuzde}): ${("-" + formatla(indirimTutar)).padStart(17)} ║\n` : ""}║ KDV (%${kdvOrani}): ${("+" + formatla(kdvTutar)).padStart(21)} ║
║ Kargo: ${(kargoBedeli === 0 ? "ÜCRETSİZ" : formatla(kargoBedeli)).padStart(24)} ║
╠═══════════════════════════════════╣
║ TOPLAM: ${formatla(genelToplam).padStart(22)} ║
╚═══════════════════════════════════╝`;
}
// Kullanım
let urun = {
isim: "Kablosuz Kulaklık",
fiyat: 499.99,
adet: 2,
indirim: 15,
kdv: 18,
kargoUcretsiz: true
};
console.log(fiyatHesapla(urun));
// null/undefined güvenliği
console.log(fiyatHesapla(null)); // Hata vermez, varsayılan değerlerle çalışır
console.log(fiyatHesapla({})); // Hata vermezBu örnekte aritmetik operatörler, karşılaştırma, ternary, optional chaining, nullish coalescing, template literal ve string metodlarını tek bir gerçekçi senaryoda görebilirsiniz.
Bitwise (Bit Düzeyinde) Operatörler — Kısa Bakış
Bit düzeyinde operatörler günlük JavaScript geliştirmede nadiren kullanılır, ama varlıklarını bilmek önemlidir:
// Temel bitwise operatörler
console.log(5 & 3); // 1 — AND (0101 & 0011 = 0001)
console.log(5 | 3); // 7 — OR (0101 | 0011 = 0111)
console.log(5 ^ 3); // 6 — XOR (0101 ^ 0011 = 0110)
console.log(~5); // -6 — NOT
console.log(5 << 1); // 10 — Sol kaydırma (5 × 2)
console.log(5 >> 1); // 2 — Sağ kaydırma (5 / 2, tam sayı)
// Pratik kullanım — hızlı tam sayıya dönüştürme
console.log(~~3.7); // 3 — Math.floor alternatifi (pozitif sayılar için)
console.log(3.7 | 0); // 3 — aynı sonuç
// Yetki kontrolü (flags/permissions)
const OKUMA = 1; // 001
const YAZMA = 2; // 010
const SILME = 4; // 100
let yetki = OKUMA | YAZMA; // 011 = 3
console.log(yetki & OKUMA); // 1 (truthy) — okuma yetkisi var
console.log(yetki & SILME); // 0 (falsy) — silme yetkisi yokÖzet
🔹 `===` her zaman kullanın,
==kaçının — type coercion beklenmedik sonuçlar doğurur🔹 Falsy değerler sadece 8 tanedir:
false,0,-0,0n,"",null,undefined,NaN— geri kalan her şey truthy (boş dizi ve nesne dahil!)🔹 `??` (nullish coalescing) sadece
null/undefinediçin çalışır,||tüm falsy değerler için —0veya""geçerli bir değerse??kullanın🔹 `?.` (optional chaining) derin nesne yapılarında güvenli erişim sağlar,
null/undefinedise hata yerineundefineddöner🔹 Ternary (
koşul ? a : b) basit koşullar için mükemmeldir, iç içe kullanımdan kaçının🔹 Operatör önceliğinde şüphe varsa parantez kullanın — hem doğru sonuç hem okunabilirlik
AI Asistan
Sorularını yanıtlamaya hazır