การวนซ้ำหมายถึงกระบวนการดึงข้อมูลจาก ชุดข้อมูล อย่างต่อเนื่องตามลำดับที่แน่นอน
แล้วความแตกต่างระหว่างการวนซ้ำและการแวะผ่านคืออะไร?
next
ส่งคืนวัตถุที่มีคุณสมบัติสองประการ
value
: ค่าถัดไปของอ็อบเจ็กต์ที่ทำซ้ำได้done
: ระบุว่ามีการดึงข้อมูลทั้งหมดแล้วหรือไม่ false
หมายความว่ายังมีข้อมูล true
หมายความว่าไม่มีข้อมูลในภายหลังเพื่อสร้างตัววนซ้ำผ่านฟังก์ชันโรงงานตัววนซ้ำ Symbol.iterator
ในวัตถุที่ทำซ้ำได้
const arr = []console.log(arr)
const arr = [1, 2, 3] const iter1 = arr[Symbol.iterator]() // สร้างตัววนซ้ำผ่านฟังก์ชันโรงงานตัววนซ้ำ `Symbol.iterator` console.log(iter1) console.log(iter1.next()) console.log(iter1.next()) console.log(iter1.next()) console.log(iter1.next()) console.log('%c%s', 'color:red;font-size:24px;', '================') const mymap = แผนที่ใหม่ () mymap.set('ชื่อ', 'clz') mymap.set('อายุ', 21) const iter2 = mymap[Symbol.iterator]() // สร้างตัววนซ้ำผ่านฟังก์ชันโรงงานตัววนซ้ำ `Symbol.iterator` console.log(iter2) console.log(iter2.next()) console.log(iter2.next()) console.log(iter2.next())
จะพบว่าตัววนซ้ำ เสร็จสมบูรณ์หลังจากรับ ค่าสุดท้าย นั่นคือเมื่อ value
ถัดไปของตัววนซ้ำ undefined
อย่างไรก็ตาม ข้อความข้างต้นยังไม่ถูกต้องนัก เมื่อ value
ถัดไปของตัววนซ้ำ undefined
คุณต้องพิจารณาด้วยว่าไม่มีค่าจริงๆ หรือไม่ หรือมีค่าในวัตถุที่ทำซ้ำได้ซึ่ง undefined
หากมีค่าในอ็อบเจ็กต์ที่สามารถทำซ้ำได้ซึ่ง undefined
นั้นจะไม่เสร็จสมบูรณ์ในขณะนี้
const arr = [1, 2, 3, ไม่ได้กำหนด] const iter1 = arr[Symbol.iterator]() // สร้างตัววนซ้ำผ่านฟังก์ชันโรงงานตัววนซ้ำ `Symbol.iterator` console.log(iter1) console.log(iter1.next()) console.log(iter1.next()) console.log(iter1.next()) console.log(iter1.next()) console.log(iter1.next())
สามารถเรียกใช้ฟังก์ชันโรงงานตัววนซ้ำได้หลายครั้งโดยไม่รบกวนซึ่งกันและกันเพื่อสร้างตัววนซ้ำหลายตัว ตัววนซ้ำที่แตกต่างกันจะไม่รบกวนซึ่งกันและกัน และจะสำรวจเฉพาะวัตถุที่สามารถวนซ้ำได้โดยอิสระเท่านั้น
const arr = [1, 2, 3] const iter1 = arr[Symbol.iterator]() // สร้างตัววนซ้ำผ่านฟังก์ชันโรงงานตัววนซ้ำ `Symbol.iterator` const iter2 = arr[สัญลักษณ์.ตัววนซ้ำ]() console.log('Iterator1:', iter1.next()) console.log('Iterator2:', iter2.next()) console.log('Iterator1:', iter1.next()) console.log('Iterator2:', iter2.next())
const arr = [1, 2, 3] const iter = arr[สัญลักษณ์.ตัววนซ้ำ]() สำหรับ (const i ของ iter) { console.log(i) // เอาต์พุต 1, 2, 3 ตามลำดับ }
หากวัตถุที่ทำซ้ำได้ได้รับการแก้ไขในระหว่างการวนซ้ำ ผลลัพธ์ที่ได้รับจากตัววนซ้ำก็จะถูกแก้ไขด้วย
const arr = [1, 2, 3] console.log(arr) const iter = arr[สัญลักษณ์.ตัววนซ้ำ]() console.log(iter.next()) ถึง[1] = 999 console.log(iter.next()) console.log(iter.next())
เมื่อเราวนซ้ำ done: true
จะมีการรายงานข้อผิดพลาดเมื่อโทรไป next
หรือไม่ก็จะไม่มีการส่งคืนสิ่งใดเลย
อย่างไรก็ตาม ไม่ ตัววนซ้ำจะอยู่ในสถานะ เสร็จสมบูรณ์แต่ยังไม่เสร็จสมบูรณ์ done: true
หมายความว่าเสร็จสมบูรณ์แล้ว แต่ยังสามารถเรียก next
ในอนาคต แม้ว่าผลลัพธ์จะเป็น { value: undefined, done: true }
เสมอ . นั่นเป็นเหตุผลที่บอก ว่าจะทำแต่ไม่ทำ
const arr = [1, 2, 3] const iter = arr[สัญลักษณ์.ตัววนซ้ำ]() console.log(iter.next()) console.log(iter.next()) console.log(iter.next()) console.log(iter.next()) console.log(iter.next()) console.log(iter.next())
จากตัวอย่างข้างต้น เราสามารถรู้ได้ว่า ตัววนซ้ำถูกสร้างขึ้นผ่านฟังก์ชันโรงงานตัววนซ้ำ Symbol.iterator
ดังนั้นเราจึงจำเป็นต้องใช้ฟังก์ชันโรงงานตัววนซ้ำ จากนั้นตัววนซ้ำสามารถเรียกใช้เมธอด next
ดังนั้น คุณยังต้อง ใช้วิธี next
ไป สำหรับฟังก์ชันโรงงานตัววนซ้ำ มันจะส่งคืนอินสแตนซ์ this
โดยตรง
ตัวอย่างตัวนับ:
ตัวนับคลาส { ตัวสร้าง (จำกัด ) { this.count = 1 นี่.ลิมิต = ขีดจำกัด } ต่อไป() { ถ้า (this.count <= this.limit) { กลับ { เสร็จสิ้น: เท็จ ค่า: this.count++ - } อื่น { กลับ { เสร็จสิ้น: จริง ค่า: ไม่ได้กำหนด } - - [สัญลักษณ์.ตัววนซ้ำ]() { คืนสิ่งนี้ }}
ตัวนับ const = ตัวนับใหม่ (3) const iter = ตัวนับ [Symbol.iterator]() console.log(iter.next()) console.log(iter.next()) console.log(iter.next()) console.log(iter.next()) console.log(iter.next())
เมื่อมองแวบแรกจะไม่มีปัญหา แต่ถ้าเราใช้ for-of
เพื่อข้ามผ่าน เราก็จะสามารถค้นหาปัญหาได้
const counter = ตัวนับใหม่ (3) สำหรับ (ปล่อยให้ฉันเป็นตัวนับ) { console.log(i)}console.log('การวนซ้ำอื่น:')สำหรับ (ปล่อยให้ฉันตอบโต้) { console.log(i)}
การใช้ for-of
loop จะทำให้ใช้แล้วทิ้งได้ เนื่องจาก count
เป็นตัวแปรของอินสแตนซ์นี้ ดังนั้นจึงใช้ตัวแปรเดียวกันในการวนซ้ำทั้งสอง อย่างไรก็ตาม หลังจากการวนซ้ำครั้งแรกของตัวแปร ตัวแปรดังกล่าวเกินขีดจำกัด ดังนั้น คุณจะไม่ได้รับอะไรเลยจากการใช้ for-of
loop อีกครั้ง ผลที่ได้คือ
คุณสามารถใส่ตัวแปร count
ในการปิด จากนั้นส่งคืนตัววนซ้ำผ่านการปิด เพื่อให้ตัววนซ้ำแต่ละตัวที่สร้างขึ้นจะสอดคล้องกับตัวนับใหม่
เคาน์เตอร์คลาส { ตัวสร้าง (จำกัด ) { นี่.ลิมิต = ขีดจำกัด } [สัญลักษณ์.ตัววนซ้ำ]() { ให้นับ = 1 ขีด จำกัด const = this.limit กลับ { // ฟังก์ชันโรงงานตัววนซ้ำจะต้องส่งคืนอ็อบเจ็กต์ด้วยเมธอดถัดไป เนื่องจากการวนซ้ำถูกนำไปใช้จริงโดยการเรียกเมธอดถัดไป next() { ถ้า (นับ <= จำกัด) { กลับ { เสร็จสิ้น: เท็จ ค่า: นับ++ - } อื่น { กลับ { เสร็จสิ้น: จริง ค่า: ไม่ได้กำหนด } - - - }}
ทดสอบ
ตัวนับ const = ตัวนับใหม่ (3) สำหรับ (ปล่อยให้ฉันเป็นตัวนับ) { console.log(i)}console.log('การวนซ้ำอื่น:')สำหรับ (ปล่อยให้ฉันตอบโต้) { console.log(i)}
ก็เหมือนกับการใช้ for-of
loop ตัววนซ้ำจะเรียกเมธอด next
อย่างชาญฉลาด เมื่อตัววนซ้ำยุติก่อนกำหนด มันจะเรียกเมธอด return
ด้วย
[สัญลักษณ์.ตัววนซ้ำ]() { ให้นับ = 1 ขีด จำกัด const = this.limit กลับ { // ฟังก์ชันโรงงานตัววนซ้ำจะต้องส่งคืนอ็อบเจ็กต์ด้วยเมธอดถัดไป เนื่องจากการวนซ้ำถูกนำไปใช้จริงโดยการเรียกเมธอดถัดไป next() { ถ้า (นับ <= จำกัด) { กลับ { เสร็จสิ้น: เท็จ ค่า: นับ++ - } อื่น { กลับ { เสร็จสิ้น: จริง ค่า: ไม่ได้กำหนด } - - กลับ() { console.log ('การยุติตัววนซ้ำก่อนกำหนด') กลับ { เสร็จสิ้น: จริง } - }}
ทดสอบ
ตัวนับ const = ตัวนับใหม่ (5) สำหรับ (ปล่อยให้ฉันเป็นตัวนับ) { ถ้า (ฉัน === 3) { หยุดพัก; - console.log(i)}
หากตัววนซ้ำไม่ได้ปิด คุณสามารถดำเนินการวนซ้ำต่อจากจุดที่คุณค้างไว้ได้ ตัววนซ้ำอาร์เรย์ไม่สามารถปิดได้
const arr = [1, 2, 3, 4, 5]const iter = arr[Symbol.iterator]()iter.return = ฟังก์ชั่น () { console.log('ออกจากตัววนซ้ำก่อนกำหนด') กลับ { เสร็จสิ้น: จริง }}สำหรับ (const i ของ iter) { console.log(i) ถ้า (ฉัน === 2) { หยุดพัก }}สำหรับ (const i ของ iter) { console.log(i)}