Objeler deÄerlerin anahtarlı bir Åekilde koleksiyon halinde tutulmasını saÄlar.
Fakat bazı durumlarda sıralı koleksiyon tutmak gerekebilir, 1., 2. ve 3. elemente ihtiyaç olabilir. ÃrneÄin kullanıcıların, ürünlerin, HTML elementlerinin liste halinde tutulmasını istediÄinizde;
Obje kullanmak mantıklı deÄildir, çünkü elemanların sırasını tutmaz bu objeler. Var olanların âarasınaâ yeni bir özellik girilemez. Objeler böyle kullanımlara uygun deÄildir.
Bunun için özel bir veri yapısı vardır. Array sıralı koleksiyonları tutar.
Tanımlama
BoÅ dizi oluÅturmak için iki yöntem vardır:
let arr = new Array();
let arr = [];
Neredeyse her zaman ikinci yazım kullanılır. BaÅlangıç deÄerlerini köÅeli parantez içinde verebilirsiniz:
let meyveler = ["Elma", "Portakal", "Erik"];
Diziler sıfır ile baÅlarlar.
let meyveler = ["Elma", "Portakal", "Erik"];
alert( meyveler[0] ); // Elma
alert( meyveler[1] ); // Portakal
alert( meyveler[2] ); // Erik
Elamanı deÄiÅtirmek mümkündür:
meyveler[2] = 'Armut'; // Åimdi ["Elma", "Portakal", "Armut"]
⦠Veya diziye yeni bir eleman eklemek mümkündür:
meyveler[3] = 'Limon'; // Åimdi ["Elma", "Portakal", "Armut", "Limon"]
Dizide bulunan elemanların boyutu length metodu ile öÄrenilebilir:
let meyveler = ["Elma", "Portakal", "Erik"];
alert( meyveler.length ); // 3
Ayrıca alert kullanarak tüm dizinin gösterilmesi de mümkündür:
let meyveler = ["Elma", "Portakal", "Erik"];
alert( meyveler ); // Elma,Portakal,Erik
Dizi her türlü elemanı tutabilir.
ÃrneÄin:
// KarmaÅık tipler
let arr = [ 'Elma', { isim: 'Ahmet' }, true, function() { alert('merhaba'); } ];
// Birinci indeksteki deÄeri al ve "isim" özelliÄini görüntüle
alert( arr[1].isim ); // John
// 3. indeksteki fonksiyonu al ve çalıÅtır.
arr[3](); // merhaba
Diziler objeler gibi virgül ile bitebilir:
let meyveler = [
"Elma",
"Portakal",
"Erik",
];
âSürekli virgülâ stili yeni eleman ekleme veya çıkarma iÅlemlerini kolaylaÅtırır.
pop/push, shift/unshift iÅlemleri için metodlar
Kuyruk dizilerin en fazla kullanıldıÄı yerdir. Bilgisayar biliminde, sıralı elemanların koleksiyonları iki operasyonu desteklemelidir:
- Sonuna yeni eleman eklemeli :
push. shiftile baÅlangıçtan eleman alındıÄında ikinci eleman birinci olmalı.
Diziler bu iki iÅlemi de destekler.
Bu iÅlemler ile çokça karÅılaÅılır. ÃrneÄin, kuyruktaki mesajların hepsinin ekranda gösterilmesi gerekebilir.
Dizilerin diÄer bir kullanım amacı ise diÄer bir veri yapısı içindir. Stack
İki operasyonu destekler
push: sona eleman ekler.pop: sondan eleman alır.
Bundan dolayı yeni elemanlar her zaman sondan alınır veya sona eklenir.
YıÄın bir deste kart olarak düÅünülebilir: yeni kartlar eklendiÄinde en üste konulur veya en üstten alınır.
YıÄına en son eklenen eleman ilk olarak alınır, Buna LIFO (Last-In-First-Out) Son giren ilk çıkar prensibi denir. Kuyruklar için ise FIFO (First-In-First-Out) yani ilk giren ilk çıkar prensibi kullanılır.
JavaScriptâte diziler yıÄın veya kuyruk olarak kullanılabilirler. BaÅlangıca veya sona yeni eleman eklenebilir veya çıkartılabilir.
Bilgisayar biliminde bu iÅlemlere izin veren veri yapılarına deque denir.
Dizilerin sonu ile ilgili metodlar:
pop-
Dizinin son elemanını döndürür:
let meyveler = ["Elma", "Portakal", "Armut"]; alert( meyveler.pop() ); // Armutu sil ve bunu ekranda bildir. alert( meyveler ); // Elma, Portakal push-
Dizinin sonuna elaman ekler:
let meyveler = ["Elma", "Portakal"]; meyveler.push("Armut"); alert( meyveler ); // Elma, Portakal, Armutfruit.push()ilefruit[fruits.length] = ...birbiri ile aynı anlama gelirler.
Dizilerin baÅlangıcı ile ilgili metodlar:
shift-
Dizinin ilk elemanını döndürür:
let meyveler = ["Elma", "Portakal", "Armut"]; alert( meyveler.shift() ); // Elmayı sil ve bunu ekranda bildir. alert( meyveler ); // Portakal, Armut unshift-
Dizinin baÅlangıcına eleman ekleme:
let meyveler = ["Portakal", "Armut"]; meyveler.unshift('Elma'); alert( meyveler ); // Elma, Portakal, Armut
push ve unshift metodları aynı anda birden fazla eleman ekleyebilirler:
let meyveler = ["Elma"];
meyveler.push("Portakal", "Armut");
meyveler.unshift("Ananas", "Limon");
// ["Ananas", "Limon", "Elma", "Portakal", "Armut"]
alert( meyveler );
Ãzellikler
Dizi özel bir tip objedir. arr[0] ile özelliÄe eriÅme aslında objelerden gelen bir yazım Åeklidir. Sayılar anahtar olarak kullanılmaktadır.
Objeleri daha geniÅleterek sıralı veri koleksiyonları ve length gibi özellikler alması saÄlanmıÅtır. Fakat derininde diziler objedir.
Hatırlarsanız, JavaScriptâte sadece 7 basit tip bulunmaktadır. Dizi obje olduÄundan obje gibi davranır.
ÃrneÄin referans ile kopyalanır:
let meyveler = ["Muz"]
let arr = meyveler; // iki deÄiÅken aynı diziye referans verir. ( referans ile kopyalama )
alert( arr === fruits ); // true
arr.push("Armut"); // diziyi referans ile düzenleme
alert( meyveler ); // Muz, Armut - 2 eleman
⦠Fakat dizileri asıl önemli kılan içinde neler olduÄudur. JavaScript motoru elemanları ardıÅık hafıza alanlarında tutmaya çalıÅır. Böylece diziler çok hızlı Åekilde çalıÅabilirler.
Fakat eÄer âsıralı koleksiyonâ olan diziden çıkılır ve obje olarak çalıÅtırılırsa her Åey bozulur.
ÃrneÄin, teknik olarak aÅaÄıdaki örnek bunu yansıtır:
let meyveler = []; // Dizi yap
meyveler[99999] = 5; // boyutundan çokça büyük bir özelliÄe veri ata.
meyveler.yas = 25; // doÄrudan özelliÄe isim vererek atama yap.
Diziler tabanda obje olduÄundan dolayı yukarıdaki iÅlem geçerlidir. İstendiÄi Åekilde özellik eklenebilir.
Fakat bu durumda JavaScript motoru bizim diziler ile deÄil de normal objeler üzerinde çalıÅtıÄımızı sanar. Bundan dolayı diziye özel optimizasyon uygulanmayacaktır.
Diziyi yanlıŠkullanma biçimleri:
- Sayısal olmayan bir özellik ekle
arr.test = 5 - Delikler yap:
arr[0]ekle sonraarr[1000]ekle ( arada hiçbir deÄer yok) - Diziyi ters sıralı Åekilde doldur,
arr[1000],arr[999]vs.
Dizileri sıralı Åekilde veri tutan özel bir yapı olarak düÅünün. Bunun için özel metodlara sahiptir. JavaScript motoru içerisinde diziler çok etkili ve hızlı bir Åekilde çalıÅtırılmak üzere ayarlanmıÅtır. Sizde bu Åekilde kullanmaya hassasiyet gösterin. EÄer özelliÄi belirtmek istiyorsanız, belki de normal obje kullanmanız gerekmektedir {}
Performans
push/pop metodları hızlı çalıÅır, shift/unshift ise yavaÅ
Peki neden dizinin baÅlangıcı ile bitiÅine eleman eklemek arasında hız farkı olmaktadır? ÃalıÅma anında neler oluyor bakalım:
meyveler.shift(); // BaÅlangıçtan bir eleman al
0 indeksinde bulunan elemanı silmek yeterli deÄildir. DiÄer elemanların tekrar numaralanması gerekmektedir.
shift metodunun yapması gereken 3 iÅlem vardır:
0indeksinde bulunan elemanın silinmesi- Tüm elemanların sola kaydırılması, indekslerin tekrar numaralandırılması
1âden0âa,2âden1âe vs. uzunluközelliÄini güncelle.
Daha fazla elaman, daha fazla taÅınma süresi , daha fazla hafıza içi iÅlem demektir.
Aynı Åey unshift için de geçerlidir: dizilerin baÅına eleman ekleneceÄi zaman öncelikle elemanların saÄa kaydırılarak indeks artırılması gerekir.
Peki push/pop için böyle iÅlemlere gerek yok mu? Sondaki elemanı alabilmek için pop metodu indexi siler ve lengthâi bir azaltır.
pop metodunun yaptıÄı iÅlemler:
fruits.pop(); // Sondan bir eleman al
pop hiçbir Åey taÅımaz çünkü diÄer elemanların indexâi deÄiÅmez. Bundan dolayı aÅırı derecede hızlıdır.
pushâda aynı Åekilde sona ekler.
Döngüler
En eski yöntem for döngüsü kullanarak indeksler üzerinden dönmektir:
let dizi = ["Elma", "Portakal", "Armut"];
for (let i = 0; i < arr.length; i++) {
alert( arr[i] );
}
Diziler için diÄer yöntem ise, for..ofâtur:
let meyveler = ["Elma", "Portakal", "Erik"];
// Dizi elemanları üzerinden döner.
for(let meyve of meyveler) {
alert( meyve );
}
for..of var olan elemanın kaçıncı eleman olduÄunun görülmesine izin vermez, sadece deÄeri döner. Fakat çoÄu durumda bu daha kısa ve yeterli bir kullanımdır.
Teknik olarak diziler objedir, bundan dolayı for..in kullanmak mümkündür.
let arr = ["Elma", "Portakal", "Erik"];
for (let key in arr) {
alert( arr[key] ); // Elma, Portakal, Erik
}
Fakat bu bazı problemlere neden olur:
-
for..indöngüsü var olan tüm özelliklerin üzerinden geçer, sadece sayısal olanların deÄil.âdizi-benzeriâ objeler bazı tarayıcı ve diÄer çevrelerde kullanılmaktadır. Bunlar âdizi gibi dururlarâ,
lengthve indeks özelliklerine sahiptirler fakat sayısal olmayan özelliklere sahip metodlar da bulunmaktadır. Genelde bunlara ihtiyaç duyulmaz.for..indöngüsü bunları da listeler. Bundan dolayı dizi-benzeri bir obje ile çalıÅılacaksa, bu âekstraâ özellikler problem teÅkil edebilir. -
for..indöngüsü genel objeler için kullanıÅlıdır, diziler için deÄil. Bundan dolayı diziler için kullanıldıÄında 10-100 kata kadar daha yavaÅtır. Tabi hala hızlı sayılır. Bu hız sadece darboÄaz (bottleneck) olduÄunda önem kazanır, aksi halde anlamsızdır. Fakat yine de bu farkı bilmek iyidir.
Genel olarak, for..in diziler ile kullanılmaz.
âlengthâ ile ilgili bir not.
length özelliÄi dizi düzenlendiÄinde otomatik olarak güncellenir. Tam olarak bu uzunluk dizideki eleman sayısı deÄildir, en büyük sayısal indeksin bir fazlasıdır.
ÃrneÄin indeksi büyük tek bir elemanlı dizi büyük uzunluk verir:
let meyveler = [];
meyveler[123] = "Elma";
alert( meyveler.length ); // 124
Genelde diziler bu Åekilde kullanılmaz.
length hakkında diÄer bir ilginç bilgi ise bu özelliÄin yazılabilir olmasıdır.
EÄer elle bu deÄeri yükseltirseniz hiçbir Åey olmaz, fakat düÅürürseniz dizideki elemanlar silinir. Bu iÅlem geri döndürülemez, örneÄin:
let arr = [1, 2, 3, 4, 5];
arr.length = 2; // 2 elemana düÅür
alert( arr ); // [1, 2]
arr.length = 5; // uzunluÄu geri al
alert( arr[3] ); // undefined: deÄer dönmez
Dizinin içerisini silmenin kolay yolu : arr.length=0.
new Array()
Dizi yaratmanın bir diÄer yolu ise aÅaÄıdaki gibidir:
let arr = new Array("Elma", "Armut", "vs");
Bu Åekilde yazım daha nadir kullanılır, [] kullanımı daha kısadır. Farklı bir özelliÄi daha vardır:
EÄer new Array sayı argümanı ile çaÄırılırsa, yeni bir boÅ dizi yaratır. İçerisine bir Åey koymaz ve dizinin boyutunu belirtilen deÄer kadar tanımlar.
Bu özellik yanlıŠkullanıma müsaittir:
let arr = new Array(2); // [2] diye bir dizi mi oluÅturacak ?
alert( arr[0] ); // undefined! böyle bir eleman yok
alert( arr.length ); // length 2
Yukarıda new Array(sayı)'nın tüm elemanları undefined döndürür.
Böyle sürprizler ile karÅılaÅmamak için genelde [] kullanılır.
Ãok Boyutlu Diziler
Dizilerin elemanları dizi olabilir. Matrisleri tutmak için çok boyutlu diziler kullanılabilir:
let matrix = [
[1, 2, 3],
[4, 5, 6],
[7, 8, 9]
];
alert( matrix[1][1] ); // merkez eleman
toString
Dizilerin kendi toString uygulaması mevcuttur. Bu dizilerin arasına virgül konularak geri döndürülür.
ÃrneÄin:
let arr = [1, 2, 3];
alert( arr ); // 1,2,3
alert( String(arr) === '1,2,3' ); // true
Åu Åekilde denenirse:
alert( [] + 1 ); // "1"
alert( [1] + 1 ); // "11"
alert( [1,2] + 1 ); // "1,21"
Dizilerin Symbol.toPrimitive özellikleri yoktur, valueOf metodu da bulunmamaktadır. Sadece toString çevirimi mevcuttur. Bundan dolayı [] boŠkarakter dizisi döndürür , [1] 1, veya [1,2] "1,2" döndürür.
"+" operatörü karakter dizisine ekleme yaptıÄında diÄer bölümü de karakter dizisine çevirir. Bundan dolayı sonraki adım Åu Åekilde görülür:
alert( "" + 1 ); // "1"
alert( "1" + 1 ); // "11"
alert( "1,2" + 1 ); // "1,21"
Ãzet
Dizi özel bir çeÅit objedir, verilerin sıralı bir Åekilde saklanması için uygun bir tiptir.
-
Tanım:
// köÅeli parantez ile (genel kullanılan) let arr = [item1, item2...]; // new Array (Ãok nadir kullanım) let arr = new Array(item1, item2...);new Array(number)verilen boyutlarda yeni bir dizi yaratır, fakat eleman olmadan. -
lengthözelliÄi dizinin boyu ve daha net olmak gerekirse son index sayısı + 1 Åeklindedir. Dizi metodları tarafından otomatik olarak ayarlanır. -
EÄer
lengthâi elle küçültürseniz dizi de kısalacaktır, tabi bu veri kayıplarına neden olabilir.
Dizi üzerinde aÅaÄıdaki iÅlemler yapılabilir:
push(...items)itemsâı sona ekler.pop()sondan bir eleman siler ve döndürür.shift()baÅlangıçtan eleman siler ve bunu döndürür.unshift(...items)baÅlangıcaitemsekler.
Dizinin elemanlarını for döngüsü ile dönme:
for(let i=0; i<arr.length; i++)â hızlı çalıÅır ve eski tarayıcılara uyarlıdır.for(let item of arr)â sadece elemanların yazımı için modern yazım saÄlar.for(let i in arr)â kullanılamaz.
Dizilere üzerinden tekrar geçilecektir. DiÄer ekleme, silme, elemanların alınması, sıralanması gibi konulara Dizi Metodları bölümünde deÄinilecektir.
Yorumlar
<code>kullanınız, birkaç satır eklemek için ise<pre>kullanın. EÄer 10 satırdan fazla kod ekleyecekseniz plnkr kullanabilirsiniz)