Destructuring, bir dizinin öğelerini ya da bir nesnenin özelliklerini tek satırda ayrı değişkenlere açmanızı sağlayan JavaScript sözdizimidir: const [a, b] = dizi veya const { ad, yas } = kisi. Spread sözdizimi (...) ise tersini yapar; bir diziyi, metni ya da nesneyi yeni bir dizi, nesne veya fonksiyon argüman listesinin içine açar. Aynı üç nokta, destructuring tarafında kullanıldığında "rest" adını alır ve geri kalan öğeleri toplar.
Bu yazıda dizi ve nesne destructuring, varsayılan değerler, yeniden adlandırma, iç içe kalıplar, spread ve rest kullanımını Node.js 24 ile denenmiş örneklerle anlatıyoruz. Sonda en çok gözden kaçan konuya, spread ile yapılan kopyaların sığ olmasına ayrıca değiniyoruz. Genel yol haritası için JavaScript öğrenme rehberine bakabilirsiniz.
Dizi destructuring

Dizi kalıbında değişkenler sıraya göre eşleşir. Virgül bırakarak öğe atlayabilir, kaynakta karşılığı olmayan değişkenlere undefined atanmasını bekleyebilirsiniz. Geçici değişken kullanmadan iki değişkenin değerini takas etmek de bu sözdizimiyle yapılır:
const renkler = ["kırmızı", "yeşil", "mavi"];
const [ilk, ikinci] = renkler;
console.log(ilk, ikinci); // kırmızı yeşil
const [, , ucuncu, dorduncu] = renkler;
console.log(ucuncu, dorduncu); // mavi undefined
// Takas
let a = 1;
let b = 3;
[a, b] = [b, a];
console.log(a, b); // 3 1Dizi destructuring aslında yalnızca dizilerle değil, her iterable ile çalışır: metin, Map ve Set ya da generator çıktısı da açılabilir. Örneğin const [ilkHarf] = "Ankara" değişkene "A" atar.
Nesne destructuring, yeniden adlandırma ve varsayılan değer
Nesne kalıbında eşleşme sıraya göre değil, özellik adına göre yapılır. { ozellik: yeniAd } yazımı değeri farklı adlı bir değişkene alır, = deger eki ise varsayılan değer tanımlar. İkisi birlikte de kullanılabilir:
const yanit = { durum: 200, veri: { id: 7, ad: "Deniz" } };
const { durum, mesaj = "yok" } = yanit;
console.log(durum, mesaj); // 200 yok
// Yeniden adlandırma
const { durum: kod } = yanit;
console.log(kod); // 200
// Yeniden adlandırma + varsayılan değer
const { zamanAsimi: sure = 30 } = yanit;
console.log(sure); // 30Varsayılan değer yalnızca undefined için çalışır
MDN'nin açıkça belirttiği bir ayrıntı: varsayılan değer, özellik hiç yoksa ya da değeri undefined ise kullanılır. Değer null ise varsayılan devreye girmez. API'den null gelebilecek alanlarda bu fark önemlidir; nullish coalescing (??) operatörü null değerini de kapsar.
const { x = 5 } = { x: undefined };
const { y = 5 } = { y: null };
console.log(x, y); // 5 null
const { z } = { z: null };
console.log(z ?? 5); // 5Varsayılan değer bir ifade olabilir ve yalnızca gerektiğinde çalıştırılır. Özellik doluysa varsayılan ifadedeki fonksiyon hiç çağrılmaz.
İç içe destructuring

Kalıplar iç içe yazılabilir; dizi ve nesne kalıplarını karıştırmak da serbesttir. Aşağıda bir API yanıtının derinindeki alanları tek ifadede alıyoruz:
const siparis = {
no: 5012,
musteri: { ad: "Selin", adres: { il: "İzmir" } },
kalemler: [{ urun: "Kitap", adet: 2 }, { urun: "Kalem", adet: 10 }],
};
const {
musteri: { ad, adres: { il } },
kalemler: [{ urun: ilkUrun }],
} = siparis;
console.log(ad, il, ilkUrun); // Selin İzmir KitapBurada yalnızca ad, il ve ilkUrun değişken olarak oluşur; musteri, adres ve kalemler sadece kalıbın yoludur. Ara seviyelerden biri undefined gelirse destructuring TypeError fırlatır. Belirsiz yapılarda ara seviyeye varsayılan değer verin: { musteri: { ad } = {} } = siparis.
Fonksiyon parametrelerinde destructuring
Destructuring en çok fonksiyon parametrelerinde işe yarar. Ayar nesnesi alan bir fonksiyon, ihtiyaç duyduğu alanları varsayılanlarıyla birlikte imzasında belirtebilir. Parametrenin tamamına da = {} vermek, fonksiyon argümansız çağrıldığında hatayı önler:
function baglan({ host = "localhost", port = 5432, ssl = false } = {}) {
return `${host}:${port} ssl=${ssl}`;
}
console.log(baglan({ port: 6543 })); // localhost:6543 ssl=false
console.log(baglan()); // localhost:5432 ssl=falseVarsayılan parametreler ve rest parametreleri (function f(...args)) default ve rest parametreler yazısında ayrıntılı anlatılıyor.
Rest: geri kalanları toplamak
Kalıbın sonuna yazılan ...ad, eşleşmeyen öğeleri toplar. Dizide geri kalan öğeler yeni bir diziye, nesnede ise henüz alınmamış kendi ve numaralandırılabilir özellikler yeni bir nesneye konur. Rest öğesi kalıbın son öğesi olmak zorundadır ve arkasından virgül gelemez. Nesneden bir alanı "çıkarmanın" pratik yolu budur:
const [bas, ...kuyruk] = [10, 20, 30, 40];
console.log(bas, kuyruk); // 10 [ 20, 30, 40 ]
const kullanici = { id: 1, ad: "Mert", sifre: "gizli" };
const { sifre, ...guvenli } = kullanici;
console.log(guvenli); // { id: 1, ad: 'Mert' }Spread: dizileri ve nesneleri açmak
Spread üç yerde kullanılır: fonksiyon çağrısının argüman listesinde, dizi literallerinde ve nesne literallerinde. Dizi ve argüman listesinde yalnızca iterable değerler açılabilir. Nesne literalinde ise değerin kendi numaralandırılabilir özellikleri kopyalanır; aynı anahtar tekrar ederse sağdaki kazanır.
const sayilar = [3, 9, 1];
console.log(Math.max(...sayilar)); // 9
const tumu = [0, ...sayilar, 10];
console.log(tumu); // [ 0, 3, 9, 1, 10 ]
const varsayilan = { tema: "acik", dil: "tr" };
const ayar = { ...varsayilan, tema: "koyu" };
console.log(ayar); // { tema: 'koyu', dil: 'tr' }
// Koşullu özellik ekleme
const admin = true;
const menu = { ana: "/", ...(admin ? { panel: "/admin" } : {}) };
console.log(menu); // { ana: '/', panel: '/admin' }
console.log([..."çay"]); // [ 'ç', 'a', 'y' ]Spread ile Object.assign() arasındaki farklar (setter çağrısı, hedefi değiştirme) Object metotları yazısında anlatılıyor.
Dikkat: spread ve rest sığ kopya üretir
[...dizi] veya { ...nesne } yeni bir dış kap oluşturur, ama içerideki nesneler kopyalanmaz; yeni kap aynı nesnelere referans tutar. MDN bunu açıkça belirtir: spread kopyalarken yalnızca bir seviye derine iner ve JavaScript'te yerel olarak derin kopya yapan bir operatör yoktur. Derin kopya için web platformundaki structuredClone() metodu kullanılabilir (Node.js'te de genel olarak tanımlıdır).
const orijinal = { ad: "Proje", etiketler: ["js"], sahip: { ad: "Ali" } };
const kopya = { ...orijinal };
kopya.ad = "Kopya";
kopya.etiketler.push("node");
kopya.sahip.ad = "Veli";
console.log(orijinal.ad); // Proje
console.log(orijinal.etiketler); // [ 'js', 'node' ]
console.log(orijinal.sahip.ad); // Veli
const derin = structuredClone(orijinal);
derin.sahip.ad = "Ayşe";
console.log(orijinal.sahip.ad); // VeliSözdizimi özeti
| Yazım | Ne yapar |
|---|---|
| const [a, b] = dizi | sıraya göre ilk iki öğeyi alır |
| const [, , c] = dizi | ilk iki öğeyi atlar |
| const { ad } = obj | ad özelliğini aynı adlı değişkene alır |
| const { ad: isim } = obj | ad özelliğini isim değişkenine alır |
| const { ad = "x" } = obj | ad undefined ise "x" kullanır (null ise kullanmaz) |
| const { a: { b } } = obj | iç içe özelliği alır |
| const [x, ...rest] = dizi | rest: geri kalanları yeni diziye toplar |
| const { a, ...rest } = obj | rest: kalan özellikleri yeni nesneye toplar |
| [...dizi1, ...dizi2] | spread: dizileri birleştirir (sığ kopya) |
| { ...obj, a: 1 } | spread: nesneyi kopyalar, a alanını ezer |
| f(...args) | spread: diziyi argüman listesine açar |
Sık yapılan hatalar

Bildirim olmadan nesne destructuring
Önceden tanımlı değişkenlere nesne kalıbıyla atama yaparken ifadeyi parantez içine almalısınız. { a, b } = obj; satırı başta süslü parantez olduğu için blok olarak yorumlanır ve sözdizimi hatası verir. Doğrusu ({ a, b } = obj); biçimidir. Satır sonlarında noktalı virgül kullanmıyorsanız bu satırın önüne bir noktalı virgül koymanız gerekebilir.
undefined veya null destructuring
try {
const { ad } = undefined;
} catch (e) {
console.log(e.message);
}
// Cannot destructure property 'ad' of 'undefined' as it is undefined.Bu hata çoğunlukla fonksiyonun argümansız çağrılmasından ya da bir API alanının eksik gelmesinden kaynaklanır. Yukarıdaki = {} varsayılanı bu durumu önler. Diğer yaygın hata mesajları için sık JavaScript hata mesajları yazısına bakabilirsiniz.
Düz nesneyi dizi içine spread etmek
[...{ a: 1 }] çalışmaz ve TypeError: ... is not iterable verir, çünkü düz nesneler iterable değildir. Değerlere ihtiyacınız varsa [...Object.values(obj)] kullanın.
Sık Sorulan Sorular
Spread ile rest arasındaki fark nedir?
Yazımları aynıdır (...), görevleri terstir. Spread bir değeri açar ve sağ tarafta, argüman listesinde veya literal içinde kullanılır. Rest birden çok değeri toplar ve destructuring kalıbının ya da parametre listesinin sonunda yer alır.
[...dizi] ile dizi.slice() arasında fark var mı?
İkisi de dizinin sığ bir kopyasını üretir. Spread herhangi bir iterable ile çalıştığı için metin, Set veya Map kaynağından dizi oluşturmak için de kullanılabilir. Dizi kopyalama ve değiştirmeyen metotlar için dizi metotları yazısına bakın.
Bir fonksiyondan birden çok değer nasıl döndürülür?
JavaScript fonksiyonu tek bir değer döndürür, ama bu değer bir dizi ya da nesne olabilir. Çağıran taraf destructuring ile parçaları doğrudan değişkenlere alır. Nesne döndürmek, çağıranın sırayı ezberlemesini gerektirmediği için genellikle daha okunaklıdır:
function minMax(dizi) {
return { min: Math.min(...dizi), max: Math.max(...dizi) };
}
const { min, max } = minMax([4, 9, 2]);
console.log(min, max); // 2 9Destructuring for...of döngüsünde kullanılabilir mi?
Evet. for (const [anahtar, deger] of map) ya da for (const { ad } of kullanicilar) gibi döngü değişkenleri de bir bağlama kalıbı (binding pattern) olabilir. Aynı durum catch bloğundaki hata değişkeni için de geçerlidir.
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 · Default ve rest parametreler · Object metotları · Optional chaining ve nullish · Dizi metotları