Apa perbedaan antara forEach
dan each
di D3js?
sumber
Pertama, .forEach()
ini bukan bagian dari d3, ini adalah fungsi asli dari array javascript. Begitu,
["a", "b", "c"].forEach(function(d, i) { console.log(d + " " + i); });
// Outputs:
a 0
b 1
c 2
Dan itu berfungsi bahkan jika d3 tidak dimuat di halaman.
Selanjutnya, d3 .each()
bekerja pada pilihan d3 (apa yang Anda dapatkan saat Anda d3.selectAll(...)
). Secara teknis, Anda dapat memanggil .forEach()
pilihan d3, karena di belakang layar, pilihan d3 adalah larik dengan fungsi tambahan (salah satunya adalah .each()
). Tetapi Anda tidak boleh melakukan itu karena:
Melakukannya tidak akan menghasilkan perilaku yang diinginkan. Mengetahui cara menggunakan .forEach()
dengan pilihan d3 untuk menghasilkan perilaku yang diinginkan akan membutuhkan pemahaman yang mendalam tentang cara kerja d3. Jadi mengapa melakukannya, jika Anda hanya dapat menggunakan bagian API yang terdokumentasi dan publik.
Ketika Anda menelepon .each(function(d, i) { })
pada pilihan d3, Anda mendapatkan lebih dari sekedar d
dan i
: fungsi akan dipanggil sehingga this
di mana saja kata kunci dalam fungsi poin ke elemen HTML DOM terkait dengan d
. Dengan kata lain console.log(this)
dari dalam function(d,i) {}
akan mencatat sesuatu seperti <div class="foo"></div>
atau elemen html apa pun itu. Dan itu berguna, karena Anda dapat memanggil fungsi pada this
objek ini untuk mengubah properti CSS, konten, atau apa pun. Biasanya, Anda menggunakan d3 untuk menyetel properti ini, seperti di d3.select(this).style('color', '#c33');
.
Takeaway utama adalah bahwa, dengan menggunakan .each()
Anda mendapatkan akses ke 3 hal yang perlu: d
, this
dan i
. Dengan .forEach()
, pada sebuah array (seperti pada contoh dari awal) Anda hanya mendapatkan 2 hal ( d
dan i
), dan Anda harus melakukan banyak pekerjaan untuk juga mengaitkan elemen HTML dengan 2 hal tersebut. Dan itu antara lain adalah bagaimana d3 bermanfaat.
this
adalah masalah dalam banyak skenario d3 saat Anda meneruskan fungsi urutan yang lebih tinggi, termasuk misalnyaselection.style("color", function(d,i) { /* here 'this' is a DOM element */ })
. Saya percaya itu sebagian mengapa kelas d3 (sepertid3.svg.axis
misalnya) tidak menggunakanprototype
metode mendefinisikan kelas - sebagai cara untuk menghindari ketergantunganthis
. Tapi saya tidak melihat bagaimanaselection[0].forEach(...)
menghindari masalah ini. Bukankah ini masalah yang sama?.forEach
menerima param kedua untuk pelingkupanthis
. Itu membuat saya menyadari bahwa Anda dapat menggunakan sesuatu yang serupa untuk mencapai efek yang sama dengan d3.each()
dengan menggunakan.bind()
metode javascript . Misalnya, kehendak lingkup berikutthis
untukwindow
dan akan console.log itu:selection.each(function() { console.log(this); }.bind(window))
.