วิธีใดที่มีประสิทธิภาพที่สุดในการกรองหรือแมป nodelist ใน ES6
จากการอ่านของฉันฉันจะใช้หนึ่งในตัวเลือกต่อไปนี้:
[...nodelist].filter
หรือ
Array.from(nodelist).filter
ท่านใดจะแนะนำ และมีวิธีที่ดีกว่าเช่นโดยไม่ต้องเกี่ยวข้องกับอาร์เรย์หรือไม่?
วิธีใดที่มีประสิทธิภาพที่สุดในการกรองหรือแมป nodelist ใน ES6
จากการอ่านของฉันฉันจะใช้หนึ่งในตัวเลือกต่อไปนี้:
[...nodelist].filter
หรือ
Array.from(nodelist).filter
ท่านใดจะแนะนำ และมีวิธีที่ดีกว่าเช่นโดยไม่ต้องเกี่ยวข้องกับอาร์เรย์หรือไม่?
...ไวยากรณ์อาจไม่รองรับโดย IDE รุ่นเก่าในขณะที่Array.from()เป็นเพียงวิธีการทั่วไป
คำตอบ:
[...nodelist] จะสร้างอาร์เรย์ของอ็อบเจ็กต์หากอ็อบเจ็กต์สามารถทำซ้ำได้Array.from(nodelist)จะสร้างอาร์เรย์ออกจากวัตถุถ้าวัตถุนั้นทำซ้ำได้หรือถ้าวัตถุนั้นมีลักษณะคล้ายอาร์เรย์ (มี.lengthและอุปกรณ์ประกอบฉากเป็นตัวเลข)ตัวอย่างทั้งสองของคุณจะเหมือนกันหากNodeList.prototype[Symbol.iterator]มีอยู่เนื่องจากทั้งสองกรณีครอบคลุมการทำซ้ำ หากสภาพแวดล้อมของคุณไม่ได้รับการกำหนดค่าให้NodeListสามารถทำซ้ำได้อย่างไรก็ตามตัวอย่างแรกของคุณจะล้มเหลวและครั้งที่สองจะสำเร็จ Babelขณะนี้ไม่ได้จัดการกับกรณีนี้อย่างถูกต้อง
ดังนั้นหากคุณNodeListสามารถทำซ้ำได้ก็ขึ้นอยู่กับคุณที่คุณใช้ ฉันน่าจะเลือกเป็นกรณี ๆ ไป ข้อดีอย่างหนึ่งArray.fromคือต้องใช้อาร์กิวเมนต์ที่สองของฟังก์ชันการแม็ปในขณะที่ข้อแรก[...iterable].map(item => item)จะต้องสร้างอาร์เรย์ชั่วคราวArray.from(iterable, item => item)จะไม่ อย่างไรก็ตามหากคุณไม่ได้ทำแผนที่รายการก็ไม่สำคัญ
TL; DR;
Array.prototype.slice.call(nodelist).filter
slice () วิธีการส่งคืนอาร์เรย์ อาร์เรย์ที่ส่งคืนเป็นสำเนาตื้นของคอลเลกชัน (NodeList)
ดังนั้นจึงทำงานได้เร็วกว่าArray.from ()
ดังนั้นจึงทำงานได้เร็วเท่ากับArray.from ()
องค์ประกอบของคอลเลกชันดั้งเดิมจะถูกคัดลอกไปยังอาร์เรย์ที่ส่งคืนดังนี้:
คำอธิบายสั้น ๆ เกี่ยวกับข้อโต้แย้ง
Array.prototype.slice (beginIndex, endIndex)
Array.prototype.slice.call (เนมสเปซ, beginIndex, endIndex)
Array.fromหรือไม่ ได้เวลาหาเครื่อง IE ตอนนี้ฉันสับสนมากเพราะฉันสามารถใช้ Array.from ใน IE10 และ IE11: \. วิธีนี้ใช้งานได้ใน IE10 + 11 แต่ฉันไม่ได้รับการผ่อนคลายโดย Array.from ทำงานเมื่อเอกสารทั้งหมดระบุเป็นอย่างอื่น
Array.fromไม่ทำงานสำหรับฉันใน IE11 Object ไม่รองรับคุณสมบัติหรือวิธีการ 'from'
Array.fromยังส่งคืนสำเนาตื้น ดังนั้นผมจึงไม่เห็นว่าคุณสรุปArray#sliceว่ามันทำงานได้เร็วกว่า
ฉันพบข้อมูลอ้างอิงที่ใช้mapโดยตรงบน NodeList โดย
Array.prototype.map.call(nodelist, fn)
ฉันยังไม่ได้ทดสอบ แต่ดูเหมือนจะเป็นไปได้ว่าสิ่งนี้จะเร็วกว่าเพราะควรเข้าถึง NodeList โดยตรง
แล้วสิ่งนี้ล่ะ:
// Be evil. Extend the prototype.
if (window.NodeList && !NodeList.prototype.filter) {
NodeList.prototype.filter = Array.prototype.filter;
}
// Use it like you'd expect:
const noClasses = document
.querySelectorAll('div')
.filter(div => div.classList.length === 0)
เป็นแนวทางเดียวกับที่กล่าวไว้ในเอกสาร MDN สำหรับ NodeList.forEach (ภายใต้ 'Polyfill') ซึ่งใช้ได้กับ IE11 , Edge, Chrome และ FF
babelแล้ว[...coll]ก็จะเรียกสำหรับสิ่งที่ไม่ได้เป็นArray.from(coll)Array