D3 javascript foreach ve each arasındaki fark


Yanıtlar:


179

İlk olarak, .forEach()d3'ün bir parçası değil, javascript dizilerinin yerel bir işlevi. Yani,

["a", "b", "c"].forEach(function(d, i) { console.log(d + " " + i); });
// Outputs:
a 0
b 1
c 2

Ve bu, sayfada d3 yüklü olmasa bile çalışır.

Daha sonra, d3'ler .each()d3 seçimleri üzerinde çalışır (ne zaman elde edersiniz d3.selectAll(...)). Teknik olarak, .forEach()bir d3 seçimini çağırabilirsiniz , çünkü perde arkasında bir d3 seçimi, ekstra fonksiyonlara sahip bir dizidir (bunlardan biri .each()). Ama bunu yapmamalısın çünkü:

  1. Bunu yapmak istenen davranışı üretmeyecektir. .forEach()İstenilen herhangi bir davranışı üretmek için bir d3 seçimiyle nasıl kullanılacağını bilmek , d3'ün iç işleyişinin yakından anlaşılmasını gerektirir. Öyleyse, API'nin sadece belgelenmiş, herkese açık bölümünü kullanabiliyorsanız neden yapasınız?

  2. Aradığınızda .each(function(d, i) { })bir d3 seçimine, daha adil daha almak dve i: işlev böyle çağrılan olduğunu thisilişkilendirilen HTML DOM öğesine o fonksiyon noktaları içindeki anahtar kelime her yerde d. Başka bir deyişle console.log(this), içeriden function(d,i) {}benzer bir şeyi <div class="foo"></div>veya html öğesi ne olursa olsun günlüğe kaydedecektir . Ve bu kullanışlıdır, çünkü o zaman thisCSS özelliklerini, içeriğini veya her neyse değiştirmek için bu nesnede function çağırabilirsiniz . Genellikle, bu özellikleri ayarlamak için d3'ü kullanırsınız d3.select(this).style('color', '#c33');.

Ana paket kullanarak, yani .each(): Eğer 3 şey erişmek Eğer gerekmez d, thisve i. İle .forEach(), bir dizi üzerinde (baştan örnekte olduğu gibi) sadece 2 şey olsun ( dve i) ve ayrıca bu 2 şey bir HTML elemanı ilişkilendirmek için işin bir demet yapmak gerekir. Ve bu, diğer şeylerin yanı sıra, d3'ün ne kadar yararlı olduğudur.


17
Harika bir cevap yazdığınız ve bunu SO'da çok yaygın olan gereksiz herhangi bir cevabı dahil etmeden yaptığınız için teşekkürler ...
Kevin H. Lin

1
Burada bir uyarı olmalı: 'this' anahtar kelimesi için farklı kapsamlara ihtiyaç duyduğunuzda ancak çağrılan fonksiyonunuzda veriye ihtiyacınız olmadığında, [0] .forEach (...) seçimi, her bir seçimden çok daha uygundur, "bu", yalnızca DOM öğelerine başvurmanın dışında anlamlıysa, üst işlevde bir "öz = bu" geçici çözümü gerektirir.
sdupton

@sdupton için kapsam belirleme this, örneğin dahil olmak üzere daha yüksek dereceli işlevlerde geçtiğiniz birçok d3 senaryosunda bir sorundur selection.style("color", function(d,i) { /* here 'this' is a DOM element */ }). Sanırım kısmen bu yüzden d3 sınıfları ( d3.svg.axisörneğin), prototypesınıfları tanımlama yöntemlerini - güvenmekten kaçınmanın bir yolu olarak kullanmıyor this. Ama selection[0].forEach(...)bu sorunu nasıl önlediğini anlamıyorum . Aynı sorun değil mi?
meetamit

1
@meetamit Array.prototype.forEach'de kullanılmak üzere 'this' alanını, her bir öğede çağrılacak işlevden sonra iletilen ikinci bir argümanla açıkça kapsama alabilirsiniz. Nesne yönelimli bir sarmalayıcıya benzeyen herhangi bir şey yazarken (ES6 sınıflarını kullanıyorum), 'bunun' açık kapsamını kaybetmek bir serseri olabilir.
sdupton

2
@sdupton, harika - Kapsam .forEachbelirleme için 2. bir parametrenin kabul edildiğini bilmiyordum this. .each()Javascript .bind()yöntemini kullanarak d3'lerle aynı etkiyi elde etmek için benzer bir şey kullanabileceğinizi fark ettim . Örneğin, aşağıdaki hususlar kapsam thisiçin windowve bunu console.log olacaktır: selection.each(function() { console.log(this); }.bind(window)).
meetamit
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.