ค้นหาเว็บไซต์

vue.js - forEach ไม่ใช่ฟังก์ชันข้อผิดพลาดกับอาเรย์ของ JavaScript


ฉันกำลังพยายามสร้างลูปง่าย ๆ:

const parent = this.el.parentElement
console.log(parent.children)
parent.children.forEach(child => {
  console.log(child)
})

แต่ฉันได้รับข้อผิดพลาดดังต่อไปนี้:

VM384:53 เกิดข้อผิดพลาดประเภทไม่ถูกต้อง: parent.children.forEach ไม่ใช่ฟังก์ชัน

แม้ว่า parent.children จะแสดงผล:

ปัญหาอาจจะเป็นอะไรได้บ้าง?

หมายเหตุ: นี่คือ JSFiddle

คำตอบ #1

ตัวเลือกแรก: เรียกใช้ forEach แบบทางอ้อม

parent.children เป็นวัตถุคล้ายอาร์เรย์ ใช้โซลูชันดังต่อไปนี้:

const parent = this.el.parentElement;

Array.prototype.forEach.call(parent.children, child => {
  console.log(child)
});

parent.children เป็นประเภท NodeList ซึ่งเป็นวัตถุคล้ายอาร์เรย์เพราะ:

  • มันมีคุณสมบัติ length ซึ่งบ่งบอกจำนวนโหนด
  • แต่ละโหนดเป็นค่าของสมบัติที่มีชื่อเป็นตัวเลข เริ่มจาก 0: {0: NodeObject, 1: NodeObject, length: 2, ...}

ดูรายละเอียดเพิ่มเติมในบทความนี้

ตัวเลือกที่สอง: ใช้โปรโตคอลที่สามารถวนซ้ำได้

parent.children คือ HTMLCollection: ซึ่งใช้โปรโตคอล iterable ในสภาพแวดล้อม ES2015 คุณสามารถใช้ HTMLCollection กับโครงสร้างใดก็ได้ที่รับ iterable

ใช้ HTMLCollection กับตัวดำเนินการกระจาย:

const parent = this.el.parentElement;

[...parent.children].forEach(child => {
  console.log(child);
});

หรือกับวัฏจักร for..of (ซึ่งเป็นตัวเลือกที่ฉันชอบ):

const parent = this.el.parentElement;

for (const child of parent.children) {
  console.log(child);
}

คำตอบ #2

parent.children ไม่ใช่อาเรย์ มันเป็น HTMLCollection และไม่มีเมธอด forEach คุณสามารถแปลงมันเป็นอาเรย์ก่อน ตัวอย่างเช่นใน ES6:

Array.from(parent.children).forEach(child => {
    console.log(child)
});

หรือใช้ตัวดำเนินการกระจาย:

[...parent.children].forEach(function (child) {
    console.log(child)
});

คำตอบ #3

เวอร์ชันที่ ง่ายหรือเด็กน้อยกว่า อย่างน้อยคุณก็มั่นใจได้ว่ามันจะทำงานได้บนอุปกรณ์ทุกชนิด โดยไม่ต้องแปลงและ ES6 :

const children = parent.children;
for (var i = 0; i < children.length; i++){
    console.log(children[i]);
}

https://jsfiddle.net/swb12kqn/5/

คำตอบ #4

parent.children จะคืนค่า node list รายการ ซึ่งทางเทคนิคคือ HTML Collection นั่นคือวัตถุที่มีลักษณะเหมือนอาร์เรย์ แต่ไม่ใช่อาร์เรย์ ดังนั้นคุณไม่สามารถเรียกใช้ฟังก์ชันอาร์เรย์กับมันโดยตรง ในบริบทนี้คุณสามารถใช้ Array.from() เพื่อแปลงมันเป็นอาร์เรย์จริงได้

Array.from(parent.children).forEach(child => {
  console.log(child)
})

คำตอบ #5

parent.children เป็น HTMLCollection ซึ่งเป็นวัตถุที่คล้าย Array ก่อนอื่นคุณต้องแปลงมันเป็น Array ที่แท้จริงเพื่อใช้เมธอดของ Array.prototype

const parent = this.el.parentElement
console.log(parent.children)
[].slice.call(parent.children).forEach(child => {
  console.log(child)
})

คำตอบ #6

คุณสามารถตรวจสอบได้ว่าคุณพิมพ์ forEach ถูกต้องหรือไม่ หากคุณพิมพ์ foreach เหมือนในภาษาโปรแกรมอื่น ๆ มันจะไม่ทำงาน

บทความที่เกี่ยวข้อง