อะไรคือความแตกต่างระหว่างforEachและeachใน D3js?
อะไรคือความแตกต่างระหว่างforEachและeachใน D3js?
คำตอบ:
ประการแรก.forEach()ไม่ได้เป็นส่วนหนึ่งของ d3 แต่เป็นฟังก์ชันดั้งเดิมของอาร์เรย์จาวาสคริปต์ ดังนั้น,
["a", "b", "c"].forEach(function(d, i) { console.log(d + " " + i); });
// Outputs:
a 0
b 1
c 2
และใช้งานได้แม้ว่าจะไม่โหลด d3 บนเพจก็ตาม
ถัดไป d3 .each()ทำงานกับการเลือก d3 (สิ่งที่คุณจะได้รับเมื่อคุณd3.selectAll(...)) ในทางเทคนิคคุณสามารถเรียก.forEach()ใช้การเลือก d3 เนื่องจากเบื้องหลังการเลือก d3 คืออาร์เรย์ที่มีฟังก์ชันพิเศษ (หนึ่งในนั้นคือ.each()) แต่คุณไม่ควรทำเช่นนั้นเพราะ:
การทำเช่นนั้นจะไม่ก่อให้เกิดพฤติกรรมที่ต้องการ การรู้วิธีใช้.forEach()กับการเลือก d3 เพื่อสร้างพฤติกรรมที่ต้องการจะต้องมีความเข้าใจอย่างใกล้ชิดเกี่ยวกับการทำงานภายในของ d3 เหตุใดจึงต้องทำเช่นนั้นหากคุณสามารถใช้เอกสารส่วนสาธารณะของ API ได้
เมื่อคุณเรียกใช้.each(function(d, i) { })ในการเลือก d3 คุณจะได้รับมากกว่าเพียงแค่การdและiฟังก์ชั่นที่ได้รับการเรียกดังกล่าวที่thisใดก็ได้ภายในคำหลักที่จุดทำงานกับองค์ประกอบ HTML DOM dที่เกี่ยวข้องกับ กล่าวอีกนัยหนึ่งconsole.log(this)จากภายในfunction(d,i) {}จะบันทึกสิ่งที่เหมือน<div class="foo"></div>หรือองค์ประกอบ html ที่เป็นองค์ประกอบ และนั่นมีประโยชน์เพราะคุณสามารถเรียกใช้ฟังก์ชันบนthisวัตถุนี้เพื่อเปลี่ยนคุณสมบัติ CSS เนื้อหาหรืออะไรก็ได้ โดยปกติคุณใช้ d3 เพื่อตั้งค่าคุณสมบัติเหล่านี้เช่นเดียวกับในd3.select(this).style('color', '#c33');.
Takeaway ที่สำคัญคือว่าการใช้.each()ที่คุณได้รับการเข้าถึง 3 สิ่งที่คุณต้องการ: d, และthis iด้วย.forEach()อาร์เรย์ (เช่นในตัวอย่างตั้งแต่ต้น) คุณจะได้รับ 2 สิ่งเท่านั้น ( dและi) และคุณต้องทำงานหลายอย่างเพื่อเชื่อมโยงองค์ประกอบ HTML กับ 2 สิ่งนั้นด้วย และเหนือสิ่งอื่นใด d3 มีประโยชน์อย่างไร
thisเป็นความกังวลในสถานการณ์ d3 selection.style("color", function(d,i) { /* here 'this' is a DOM element */ })มากมายที่คุณผ่านในฟังก์ชั่นการสั่งซื้อที่สูงขึ้นรวมทั้งตัวอย่าง ผมเชื่อว่าเป็นบางส่วนทำไมเรียน d3 (เหมือนd3.svg.axisตัวอย่าง) ไม่ได้ใช้prototypeวิธีการของการกำหนดชั้นเรียน - thisเป็นวิธีที่จะหลีกเลี่ยงการพึ่งพา แต่ฉันไม่เห็นว่าselection[0].forEach(...)จะหลีกเลี่ยงปัญหานี้ได้อย่างไร มันไม่ใช่ปัญหาเดียวกันเหรอ?
.forEachได้รับการยอมรับพระรามที่ 2 thisสำหรับการกำหนดขอบเขต มันทำให้ฉันรู้ว่าคุณสามารถใช้สิ่งที่คล้ายกันเพื่อให้ได้เอฟเฟกต์เดียวกันกับ d3 .each()โดยใช้.bind()วิธีการของจาวาสคริปต์ ยกตัวอย่างเช่นขอบเขตต่อไปนี้จะthisไปwindowและจะ console.log selection.each(function() { console.log(this); }.bind(window))มัน