Optional chaining (?.), bir özelliğe erişirken ya da bir fonksiyonu çağırırken soldaki değer null veya undefined ise hata fırlatmak yerine işlemi durdurup undefined döndürür. Nullish coalescing (??) ise soldaki değer yalnızca null veya undefined olduğunda sağdaki varsayılan değeri verir. ??= da aynı mantıkla, değişken boşsa atama yapar.
Bu üç operatör birlikte, iç içe ve eksik olabilen verilerle (API yanıtları, ayar dosyaları, form verileri) çalışırken hem kısa hem güvenli kod yazmanızı sağlar. En önemli fark || operatörüyle ilgilidir: ||, 0 ve boş metin gibi geçerli değerleri de "yok" sayar. Aşağıdaki tüm örnekler Node.js 24 ile çalıştırıldı.
?. ile güvenli özellik erişimi

Üç biçimi vardır: obj?.ozellik, obj?.[ifade] ve fonksiyon?.(argumanlar). Köşeli parantezli biçim özellikle dizi indeksleri ve değişken anahtarlar için kullanışlıdır.
const kullanici = {
ad: "Zeynep",
adres: { sehir: "İzmir" },
etiketler: ["yeni"],
};
console.log(kullanici.adres?.sehir); // İzmir
console.log(kullanici.fatura?.sehir); // undefined
console.log(kullanici.etiketler?.[0]); // yeni
console.log(kullanici.bildir?.("merhaba")); // undefined
try {
kullanici.fatura.sehir;
} catch (e) {
console.log(e.message); // Cannot read properties of undefined (reading 'sehir')
}?. öncesinde yaygın olan obj.a && obj.a.b kalıbının bir zaafı vardır: obj.a değeri 0 veya boş metin gibi falsy ama geçerli bir değerse ifade o değerde durur. ?. yalnızca null ve undefined için durur.
Kısa devre: zincirin geri kalanı hiç çalışmaz
Soldaki değer nullish olduğunda yalnızca o adım değil, aynı zincirin devamındaki tüm erişimler ve köşeli parantez içindeki ifadeler de atlanır. Zinciri parantezle bölerseniz bu koruma parantezin dışına taşmaz.
const bos = null;
let i = 0;
bos?.[i++];
console.log(i); // 0 (i++ hiç çalışmadı)
console.log(bos?.a.b.c); // undefined (a.b.c de atlandı)
try {
(bos?.a).b;
} catch (e) {
console.log(e.constructor.name); // TypeError
}Fonksiyon çağrısında ?. ve sınırları
nesne.metot?.() yalnızca metot null veya undefined ise çağrıyı atlar. Özellik var ama fonksiyon değilse yine TypeError alırsınız. Nesnenin kendisi de boş olabiliyorsa her iki adıma da ?. koymanız gerekir: nesne?.metot?.(). İsteğe bağlı geri çağırma fonksiyonlarında bu kalıp çok işe yarar; geri çağırma kavramı için callback yazısına bakabilirsiniz.
const o = { yontem: 42 };
try {
o.yontem?.();
} catch (e) {
console.log(e.message); // o.yontem is not a function
}
function kaydet(veri, hataOlursa) {
try {
throw new Error("disk dolu");
} catch (e) {
hataOlursa?.(e.message); // verilmediyse sessizce geçer
}
}
kaydet({}); // çıktı yok
kaydet({}, (m) => console.log("Hata:", m)); // Hata: disk dolu?? ile varsayılan değer: || operatöründen farkı
a ?? b, a null veya undefined ise b, değilse a döndürür. a || b ise a herhangi bir falsy değer olduğunda (0, "", NaN, false, null, undefined) b verir. Sayfa başına kayıt sayısı, indirim oranı veya boş bırakılmış bir açıklama gibi alanlarda bu fark doğrudan hataya dönüşür.
const ayar = { sayfaBasi: 0, baslik: "", tema: null };
console.log(ayar.sayfaBasi || 20); // 20 (0 kayboldu)
console.log(ayar.sayfaBasi ?? 20); // 0
console.log(JSON.stringify(ayar.baslik || "Adsız")); // "Adsız"
console.log(JSON.stringify(ayar.baslik ?? "Adsız")); // ""
console.log(ayar.tema ?? "açık"); // açık
console.log(ayar.dil ?? "tr"); // tr| Sol değer | a || "x" | a ?? "x" |
|---|---|---|
| null | x | x |
| undefined | x | x |
| 0 | x | 0 |
| "" (boş metin) | x | "" |
| false | x | false |
| NaN | x | NaN |
| "metin" | metin | metin |
Falsy kavramı ve tip dönüşümünün geri kalanı tip dönüşümü yazısında anlatılıyor.
?? de kısa devre yapar
Sol taraf nullish değilse sağ taraf hiç değerlendirilmez. Varsayılan değeri pahalı bir fonksiyon üretiyorsa bu, gereksiz çalışmayı önler.
function varsayilan() {
console.log("varsayilan() çalıştı");
return "yedek";
}
console.log(undefined ?? varsayilan());
// varsayilan() çalıştı
// yedek
console.log(false ?? varsayilan()); // false?. ve ?? birlikte
İkisi doğal olarak birleşir: önce güvenli erişim, sonra eksikse varsayılan değer.
function sehirGetir(musteri) {
return musteri?.adres?.sehir ?? "Bilinmeyen şehir";
}
console.log(sehirGetir({ adres: { sehir: "Bursa" } })); // Bursa
console.log(sehirGetir({ ad: "Can" })); // Bilinmeyen şehir
console.log(sehirGetir(undefined)); // Bilinmeyen şehirGerçek senaryo: API yanıtındaki ayarları okumak
Bir servisten gelen JSON yanıtında bazı alanlar hiç gelmeyebilir, bazıları null olabilir, bazıları da bilerek false veya 0 olarak ayarlanmıştır. Aşağıdaki örnekte kullanıcı bildirimleri kapatmış (false), dil tercihi boş (null) ve profil bilgisi hiç yok. ?. eksik ara nesnelerden korur, ?? yalnızca gerçekten boş olanlara varsayılan değer verir:
const yanit = {
veri: {
kullanici: { ad: "Ece", ayarlar: { bildirim: false, dil: null } },
},
};
const k = yanit.veri?.kullanici;
const bildirim = k?.ayarlar?.bildirim ?? true;
const dil = k?.ayarlar?.dil ?? "tr";
const foto = k?.profil?.foto ?? "/varsayilan.png";
console.log(bildirim, dil, foto); // false tr /varsayilan.png
// || ile yazılsaydı kullanıcının tercihi kaybolurdu:
console.log(k?.ayarlar?.bildirim || true); // trueSon satırdaki hata kolay gözden kaçar: kullanıcı bildirimleri kapattığı hâlde kod onları açık sayar. Boolean ve sayısal ayarlarda varsayılan değer verirken ?? tercih etmek, bu tür sessiz hataların önüne geçer. JSON verisini ayrıştırma adımı için JSON.parse yazısına bakabilirsiniz.
??= ile yalnızca boşsa atama
x ??= y, x ?? (x = y) ile eşdeğerdir; tek farkı x ifadesinin bir kez değerlendirilmesidir. Sol taraf boş değilse atama yapılmaz, sağ taraf hiç çalıştırılmaz ve setter tetiklenmez. Ayar nesnelerine varsayılan değer yerleştirmek için idealdir; parametre varsayılanlarından farklı olarak null değerini de "boş" sayar.
function ayarla(secenek) {
secenek.zamanAsimi ??= 5000;
secenek.deneme ??= 3;
return secenek;
}
console.log(ayarla({ zamanAsimi: 0 })); // { zamanAsimi: 0, deneme: 3 }
console.log(ayarla({ deneme: null })); // { deneme: 3, zamanAsimi: 5000 }
function selamla(ad = "misafir") {
return ad;
}
console.log(selamla(undefined), selamla(null)); // misafir nullSon iki satır önemli bir farkı gösteriyor: varsayılan parametre yalnızca undefined için devreye girer, null geçildiğinde null kalır. Parametre varsayılanlarının ayrıntısı default ve rest parametreler yazısında.
Yaygın hatalar

?? ile || operatörünü parantezsiz karıştırmak
Dil, ?? operatörünün || veya && ile parantezsiz aynı ifadede kullanılmasına izin vermez; kod çalışmadan önce SyntaxError alırsınız. Önceliği parantezle açıkça belirtin.
// null || undefined ?? "foo"; // SyntaxError
console.log((null || undefined) ?? "foo"); // fooDiğer tuzaklar
- Atamanın solunda ?. kullanmak:
obj?.ozellik = 1geçersizdir (SyntaxError). Önce nesnenin var olduğunu kontrol edin veya??=ile oluşturun. - Tanımlanmamış değişkende ?. kullanmak:
tanimsizDegisken?.xyineReferenceErrorverir.?.yalnızca değeriundefinedolan, ama bildirilmiş isimleri korur. - Her yere ?. koymak: Hiç boş olmaması gereken bir değeri
?.ile okumak, hatayı gizleyip sorunu ileriye taşır. Yalnızca gerçekten isteğe bağlı olan alanlarda kullanın. - new ve etiketli şablonla birleştirmek:
new Map?.()veString?.raw`...`sözdizimi hatasıdır.
Sık Sorulan Sorular
?. ne döndürür, null mu undefined mı?
Soldaki değer null olsa bile kısa devre sonucu her zaman undefined olur.
|| kullanmak ne zaman hâlâ doğru?
Boş metin, 0 veya false değerlerini de "değer yok" saymak istiyorsanız || doğru tercihtir. Örneğin boş bırakılmış bir arama kutusunu varsayılan metinle değiştirmek istiyorsanız || işinizi görür.
??= ile ||= arasındaki fark nedir?
??= yalnızca null ve undefined için atar; ||= tüm falsy değerler için atar. 0 geçerli bir değerse ??= kullanın.
Bu operatörler eski ortamlarda çalışır mı?
Güncel tarayıcılar ve Node.js 24 destekler. Hedeflediğiniz ortamlar için MDN uyumluluk tablosuna bakın.
Marka adları sahiplerine aittir. Bu yazı bağımsız bir teknik rehberdir; adı geçen kuruluşlarla bayilik veya ortaklık ilişkisi bulunduğu anlamına gelmez.
İlgili içerikler: JavaScript öğrenme rehberi · Tip dönüşümü · Eşitlik operatörleri · Default ve rest parametreler · Destructuring ve spread · Sık JavaScript hata mesajları