Geleneksel döngüleri kullanarak veri koleksiyonları üzerinde yineleme yapmak, özellikle çok büyük miktarda veriyle uğraşırken hızla külfetli ve yavaş olabilir.
JavaScript Oluşturucuları ve Yineleyicileri, büyük veri koleksiyonları üzerinde verimli bir şekilde yineleme yapmak için bir çözüm sunar. Bunları kullanarak yineleme akışını kontrol edebilir, değerleri birer birer verebilir ve yineleme sürecini duraklatabilir ve devam ettirebilirsiniz.
Burada bir JavaScript yineleyicinin temellerini ve dahili özelliklerini ve bir yineleyiciyi manuel olarak ve bir oluşturucu kullanarak nasıl oluşturabileceğinizi ele alacaksınız.
JavaScript Yineleyiciler
Yineleyici, yineleyici protokolünü uygulayan bir JavaScript nesnesidir. Bu nesneler, bunu bir Sonraki yöntem. Bu yöntem, uygulayan bir nesne döndürür. YineleyiciSonucu arayüz.
bu YineleyiciSonucu arayüz iki özelliği içerir: Tamamlandı Ve değer. bu Tamamlandı özellik, döndüren bir boole'dir YANLIŞ yineleyici, dizisindeki bir sonraki değeri üretebilirse veya doğru yineleyici sırasını tamamladıysa.
bu değer özelliği, dizisi sırasında yineleyici tarafından döndürülen bir JavaScript değeridir. Bir yineleyici dizisini tamamladığında (ne zaman Tamamlandıdoğru), bu özellik döndürür Tanımsız.
Adından da anlaşılacağı gibi yineleyiciler, diziler veya haritalar gibi JavaScript nesneleri üzerinde "yinelemenize" izin verir. Bu davranış yinelenebilir protokol nedeniyle mümkündür.
JavaScript'te yinelenebilir protokol, üzerinde yineleme yapabileceğiniz nesneleri tanımlamanın standart bir yoludur. ... için döngü.
Örneğin:
sabit meyveler = ["Muz", "Mango", "Elma", "üzüm"];
için (sabit yineleyici ile ilgili meyveler) {
konsol.log (yineleyici);
}
/*
Muz
Mango
Elma
üzüm
*/
Bu örnek, meyveler kullanarak dizi ... için döngü. Her yinelemede, geçerli değeri konsola kaydeder. Diziler yinelenebilir olduğundan bu mümkündür.
Diziler, Dizeler gibi bazı JavaScript türleri, Kümeler ve Haritalar, yerleşik yinelemelerdir çünkü onlar (veya prototip zincirindeki nesnelerden biri) bir @@yineleyici yöntem.
Nesneler gibi diğer türler varsayılan olarak yinelenemez.
Örneğin:
sabit iterObject = {
arabalar: ["Tesla", "BMW", "Toyota"],
hayvanlar: ["Kedi", "Köpek", "Hamster"],
yiyecek: ["Burger", "Pizza", "Makarna"],
};için (sabit yineleyici ile ilgili iterObject) {
konsol.log (yineleyici);
}
// TypeError: iterObject yinelenemez
Bu örnek, yinelenemeyen bir nesne üzerinde yineleme yapmaya çalıştığınızda ne olduğunu gösterir.
Bir Nesneyi Yinelenebilir Hale Getirme
Bir nesneyi yinelenebilir yapmak için, bir Symbol.yineleyici nesne üzerindeki yöntem. Yinelenebilir hale gelmesi için, bu yöntemin aşağıdakileri uygulayan bir nesne döndürmesi gerekir: YineleyiciSonucu arayüz.
bu Symbol.yineleyici sembolü ile aynı amaca hizmet eder. @@yineleyici ve "şartnamede" birbirinin yerine kullanılabilir, ancak kodda şu şekilde kullanılamaz: @@yineleyici geçerli JavaScript sözdizimi değil.
Aşağıdaki kod blokları, bir nesneyi kullanarak yinelenebilir hale getirmenin bir örneğini sağlar. iterObject.
İlk olarak şunu ekleyin: Symbol.yineleyici yöntemi iterObject kullanarak bir işlev deklarasyon.
Şöyle:
iterNesne[Sembol.yineleyici] = işlev () {
// Sonraki kod blokları buraya gelir...
}
Ardından, yinelenebilir hale getirmek istediğiniz nesnedeki tüm anahtarlara erişmeniz gerekir. kullanarak tuşlara erişebilirsiniz. nesne.anahtarlar bir nesnenin numaralandırılabilir özelliklerinin bir dizisini döndüren yöntem. Bir dizi döndürmek için iterObject’nin anahtarları, Bu argüman olarak anahtar kelime nesne.anahtarlar.
Örneğin:
izin vermek objProperties = Nesne.anahtarlar(Bu)
Bu diziye erişim, nesnenin yineleme davranışını tanımlamanıza izin verecektir.
Ardından, nesnenin yinelemelerini takip etmeniz gerekir. Bunu sayaç değişkenlerini kullanarak başarabilirsiniz.
Örneğin:
izin vermek özellik dizini = 0;
izin vermek çocuk dizini = 0;
Nesne özelliklerini takip etmek için ilk sayaç değişkenini ve özelliğin alt öğelerini takip etmek için ikincisini kullanacaksınız.
Ardından, uygulamanız ve geri göndermeniz gerekir. Sonraki yöntem.
Şöyle:
geri dönmek {
Sonraki() {
// Sonraki kod blokları buraya gelir...
}
}
İçinde Sonraki yönteminde, nesnenin tamamı yinelendiğinde ortaya çıkan bir uç durumu ele almanız gerekir. Edge kasasını işlemek için, bir nesneyi döndürmeniz gerekir. değer ayarlanır Tanımsız Ve Tamamlandı ayarlanır doğru.
Bu durum ele alınmazsa, nesne üzerinde yinelemeye çalışmak sonsuz bir döngüye neden olur.
Edge davasının nasıl ele alınacağı aşağıda açıklanmıştır:
eğer (özellik dizini > objÖzellikler.uzunluk- 1) {
geri dönmek {
değer: Tanımsız,
Tamamlandı: doğru,
};
}
Ardından, daha önce bildirdiğiniz sayaç değişkenlerini kullanarak nesne özelliklerine ve bunların alt öğelerine erişmeniz gerekir.
Şöyle:
// Üst ve alt özelliklere erişme
sabit özellikler = Bu[objProperties[özellikIndex]];
sabit özellik = özellikler[childIndex];
Ardından, sayaç değişkenlerini artırmak için bir mantık uygulamanız gerekir. Mantık sıfırlamalıdır çocuk dizini bir özelliğin dizisinde daha fazla öğe bulunmadığında ve nesnede bir sonraki özelliğe geçin. Ek olarak, artırmalı çocuk dizini, geçerli özelliğin dizisinde hala öğeler varsa.
Örneğin:
// Dizin artırma mantığı
if (childIndex >= özellikler.uzunluk - 1) {
// alt dizide başka öğe yoksa
// Sıfırlaçocukdizin
çocuk Dizini = 0;
// Sonraki özelliğe geç
özellikIndex++;
} başka {
// Alt dizideki bir sonraki öğeye git
çocuk dizini++
}
Son olarak, ile bir nesne döndür Tamamlandı özellik ayarlandı YANLIŞ ve değer özellik, yinelemedeki geçerli alt öğeye ayarlandı.
Örneğin:
geri dönmek {
Tamamlandı: YANLIŞ,
değer: özellik,
};
tamamlandı Symbol.yineleyici işlevi aşağıdaki kod bloğuna benzer olmalıdır:
iterNesne[Sembol.yineleyici] = işlev () {
sabit objProperties = Nesne.anahtarlar(Bu);
izin vermek özellik dizini = 0;
izin vermek çocuk dizini = 0;geri dönmek {
Sonraki: () => {
//Edge durumu işleme
eğer (özellik dizini > objÖzellikler.uzunluk- 1) {
geri dönmek {
değer: Tanımsız,
Tamamlandı: doğru,
};
}// Üst ve alt özelliklere erişme
sabit özellikler = Bu[objProperties[özellikIndex]];
sabit özellik = özellikler[childIndex];// Dizin artırma mantığı
if (childIndex >= özellikler.uzunluk - 1) {
// alt dizide başka öğe yoksa
// Sıfırlaçocukdizin
çocuk Dizini = 0;
// Sonraki özelliğe geç
özellikIndex++;
} başka {
// Alt dizideki bir sonraki öğeye git
çocuk dizini++
}
geri dönmek {
Tamamlandı: YANLIŞ,
değer: özellik,
};
},
};
};
çalışan ... için döngü iterObject bu uygulamadan sonra, uyguladığı için bir hata atmaz. Symbol.yineleyici yöntem.
Yineleyicileri yukarıda yaptığımız gibi manuel olarak uygulamak, hataya çok açık olduğundan ve mantığın yönetilmesi zor olabileceğinden önerilmez.
JavaScript Üreticileri
Bir JavaScript oluşturucu, yürütmesini herhangi bir noktada duraklatabileceğiniz ve devam ettirebileceğiniz bir işlevdir. Bu davranış, zaman içinde bir dizi değer üretmesine izin verir.
Bir Oluşturucu döndüren bir işlev olan bir oluşturucu işlevi, yineleyiciler oluşturmaya bir alternatif sağlar.
JavaScript'te bir işlev bildirimi oluşturduğunuz şekilde bir oluşturucu işlevi oluşturabilirsiniz. Tek fark, bir yıldız işareti (*) işlev anahtar sözcüğüne.
Örneğin:
işlev* örnek () {
geri dönmek"Jeneratör"
}
JavaScript'te normal bir işlevi çağırdığınızda, işlevi tarafından belirtilen değeri döndürür. geri dönmek anahtar kelime veya Tanımsız aksi takdirde. Ancak bir oluşturucu işlevi hemen herhangi bir değer döndürmez. Bir değişkene atayabileceğiniz bir Jeneratör nesnesi döndürür.
Yineleyicinin geçerli değerine erişmek için, Sonraki Generator nesnesindeki yöntem.
Örneğin:
sabit gen = örnek();
console.log (gen.next()); // { değer: 'Jeneratör', Tamamlandı: doğru }
Yukarıdaki örnekte, değer mülkiyet bir geldi geri dönmek anahtar kelime, oluşturucuyu etkili bir şekilde sonlandırıyor. Bu davranış, üreteç işlevlerinde genellikle istenmeyen bir durumdur, çünkü onları normal işlevlerden ayıran şey yürütmeyi duraklatma ve yeniden başlatma yeteneğidir.
Getiri Anahtar Kelimesi
bu teslim olmak anahtar kelime, bir oluşturucu işlevinin yürütülmesini duraklatarak ve onu takip eden değeri döndürerek oluşturuculardaki değerler arasında yineleme yapmak için bir yol sağlar.
Örneğin:
işlev* örnek() {
teslim olmak"Model S"
teslim olmak"Model X"
teslim olmak"Siber Kamyon"geri dönmek"Tesla"
}sabit gen = örnek();
console.log (gen.next()); // { değer: "Model S", Tamamlandı: YANLIŞ }
Yukarıdaki örnekte, Sonraki yöntem çağrılır örnek jeneratör, her karşılaştığında duraklayacaktır. teslim olmak anahtar kelime. bu Tamamlandı özellik ayrıca şu şekilde ayarlanacaktır: YANLIŞ karşılaşana kadar geri dönmek anahtar kelime.
arama Sonraki yöntem üzerinde birden çok kez örnek jeneratör, bunu göstermek için çıktınız olarak aşağıdakilere sahip olacaksınız.
console.log (gen.next()); // { değer: "Model X", Tamamlandı: YANLIŞ }
console.log (gen.next()); // { değer: "Siber Kamyon", Tamamlandı: YANLIŞ }
console.log (gen.next()); // { değer: 'Tesla', Tamamlandı: doğru }
konsol.log (gen.sonraki()); // { değer: tanımsız, bitti: doğru }
Ayrıca şunu kullanarak bir Jeneratör nesnesi üzerinde yineleme yapabilirsiniz: ... için döngü.
Örneğin:
için (sabit yineleyici ile ilgili gen) {
konsol.log (yineleyici);
}
/*
Model S
Model X
Siber Kamyon
*/
Yineleyicileri ve Oluşturucuları Kullanma
Yineleyiciler ve oluşturucular soyut kavramlar gibi görünse de öyle değildir. Sonsuz veri akışları ve veri koleksiyonlarıyla çalışırken yardımcı olabilirler. Bunları benzersiz tanımlayıcılar oluşturmak için de kullanabilirsiniz. MobX-State-Tree (MST) gibi durum yönetimi kitaplıkları da bunları gizli olarak kullanır.