forEach जावास्क्रिप्ट सरणी के साथ एक फ़ंक्शन त्रुटि नहीं है


145

मैं एक साधारण लूप बनाने की कोशिश कर रहा हूं:

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

लेकिन मुझे निम्नलिखित त्रुटि मिलती है:

VM384: 53 अनकैप्ड टाइपर्रर: parent.children.forEach कोई फ़ंक्शन नहीं है

हालांकि parent.childrenलॉग:

यहाँ छवि विवरण दर्ज करें

क्या समस्या हो सकती है?

नोट: यहाँ एक JSFiddle है


तत्व के साथ एक ही समस्या होती है। भाई
बहन

@ हाँ, क्योंकि element.siblings में HTMLCollection और HTMLCollections के पास forEach () विधि नहीं है
Freddo

1
हे तुम, Google खोजकर्ता! यदि आप इस दोहरे चेक को पढ़ रहे हैं कि यह foreach के बजाय एक पूंजी E के साथ है तो ....
रॉबर्ट सिनक्लेयर

जवाबों:


127

पहला विकल्प: अप्रत्यक्ष रूप से 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: जो चलने योग्य प्रोटोकॉल को लागू करता है । ES2015 के वातावरण में, आप HTMLCollectionकिसी भी निर्माण के साथ उपयोग कर सकते हैं जो पुनरावृत्तियों को स्वीकार करता है।

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);
}

जब मैं आपके समाधान का उपयोग करता हूं तो मुझे और कोई समस्या नहीं है, लेकिन अनाम फ़ंक्शन के अंदर कोड निष्पादित नहीं किया गया है। .so ..
Jérémy

आपको कौन सा ब्राउज़र उपयोग करना है ताकि parent.children आपको बताए कि यह एक नोडलिस्ट है। फ़ायरफ़ॉक्स पर, यह मुझे बताता है कि एक HTMLCollection है। यदि यह एक nodeList था, .forEach () काम करेगा
Freddo

104

parent.childrenएक सरणी नहीं है। यह HTMLCollection है और इसमें forEachमेथड नहीं है । आप इसे पहले सरणी में बदल सकते हैं। उदाहरण के लिए ES6 में:

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

या स्प्रेड ऑपरेटर का उपयोग करना:

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

9
मैं इस समाधान को ऐरे प्रोटोटाइप के साथ खिलवाड़ करने से ज्यादा पसंद करता हूं।
ड्यूट

और यह उत्तर ओपी प्रश्न का सही उत्तर है। parent.children एक HTMLCollection है जिसमें एक .for विधि नहीं है
Freddo

18

parent.childrenएक नोड सूची सूची, तकनीकी रूप से एक html संग्रह लौटाएगा । यह ऑब्जेक्ट की तरह एक सरणी है, लेकिन एक सरणी नहीं है, इसलिए आप सीधे इस पर सरणी फ़ंक्शन नहीं कह सकते। इस संदर्भ में आप इसका उपयोग Array.from()वास्तविक सरणी में परिवर्तित करने के लिए कर सकते हैं ,

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

नहीं, parent.children एक नोडलिस्ट लेकिन एक HTML संग्रह वापस नहीं करता है। एक ही बात नहीं है। यदि यह एक nodeList था, .forEach काम करेगा
Freddo

12

एक अधिक भोला संस्करण, कम से कम आपको यकीन है कि यह रूपांतरण और ES6 के बिना सभी उपकरणों पर काम करेगा:

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

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


2
अपविटेड क्योंकि ये सभी नए ES6 फ़ंक्शंस बिल्कुल वही पुरानी पुरानी चीज़ करते हैं जो एक उपलब्ध थी, लेकिन एक गंदे तरीके से, जैसा कि हमेशा JS के साथ होता है
Freddo

8

parent.childrenएक है HTMLCollectionजो सरणी जैसी वस्तु है। सबसे पहले, आपको इसे तरीकों Arrayका उपयोग करने के लिए वास्तविक में बदलना होगा Array.prototype

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

2
या इसे रूपांतरित नहीं करते हैं, लेकिन उपयोग .call () ऑन .forEach () का उपयोग करते हैं?
nnnnnn

@nnnnnn नीचे मेरा जवाब देखें।
दिमित्री पावलुटिन

सरणी जैसी वस्तु को एक सरणी में बदलने के कई तरीके हैं :) यह एक है
दिमित्री

@DmitriyLoskutov आपको इसे परिवर्तित करने की आवश्यकता नहीं है - जावास्क्रिप्ट एक बतख टाइपिंग भाषा है। बस इस सुविधा का उपयोग करें।
दिमित्री पावलुटिन

5

ऐसा इसलिए parent.childrenहै क्योंकि एक NodeList है , और यह .forEachविधि का समर्थन नहीं करता है (क्योंकि NodeList संरचना की तरह एक सरणी है, लेकिन एक सरणी नहीं है), इसलिए इसे पहले उपयोग करके इसे सरणी में परिवर्तित करके कॉल करने का प्रयास करें।

var children = [].slice.call(parent.children);
children.forEach(yourFunc);

नहीं, यह एक नोडलिस्ट नहीं है, यह एक HTML संग्रह है
फ्रेडो

5

इसके लिए कोई आवश्यकता नहीं हैforEach , आप केवल fromदूसरे पैरामीटर का उपयोग करके पुनरावृत्ति कर सकते हैं , जैसे:

let nodeList = [{0: [{'a':1,'b':2},{'c':3}]},{1:[]}]
Array.from(nodeList, child => {
  console.log(child)
});


दुखद खबर यह है कि parent.children एक नोडलिस्ट नहीं है ... .from () काम नहीं करेगा।
फ्रेडो जूल

@Cedric यदि आपकी वस्तु NodeList नहीं है, तो आपको विशेष रूप से इसे संबोधित करने के लिए एक नया प्रश्न पूछना चाहिए। यहां, डाउनवोटिंग का उपयोग तब किया जाता है जब उत्तर आंतरिक रूप से गलत या हानिकारक होता है और जैसा कि आप कोड स्निपेट द्वारा देख सकते हैं, ऑब्जेक्ट के सभी तत्व पुनरावृत्त और मुद्रित होते हैं, जो ओपी के प्रश्न का लक्ष्य था।
आर्मफूट

हां, समस्या यह है कि एक HTML संग्रह से संबंधित ओपी का प्रश्न, एक नोडलिस्ट नहीं है ... इसलिए उत्तर केवल सवाल का जवाब नहीं दे रहा था
फ्रेडो

@ यह उत्तर एक HTML संग्रह पर भी पुनरावृति करेगा क्योंकि Array.fromपहले पैरामीटर में दी गई वस्तु को एक अरै में परिवर्तित करता है। परिणाम एक अतिरिक्त लूप ( MDN डॉक्स) की आवश्यकता के बिना madox2 के उत्तर के समान है । forEachArray.from
आर्मफूट

4

यदि आप NodeListइस तरह से लूप करने की कोशिश कर रहे हैं :

const allParagraphs = document.querySelectorAll("p");

मैं अत्यधिक इस तरह से लूप की सलाह देता हूं:

Array.prototype.forEach.call(allParagraphs , function(el) {
    // Write your code here
})

व्यक्तिगत रूप से, मैंने कई तरीकों की कोशिश की है, लेकिन उनमें से अधिकांश ने काम नहीं किया, क्योंकि मैं एक पर लूप करना चाहता था NodeList, लेकिन यह एक आकर्षण की तरह काम करता है, इसे आज़माएं!

यह NodeListएक ऐरे नहीं है, लेकिन हम इसे एक ऐरे के रूप में मानते हैं, Array.इसलिए, आपको यह जानना होगा कि पुराने ब्राउज़र में यह समर्थित नहीं है!

के बारे में अधिक जानकारी चाहिए NodeList? कृपया MDN पर इसके प्रलेखन को पढ़ें ।


1
यह उत्तर स्पष्ट रूप से नोडलिस्ट पर काम करता है। परेशानी है माता-पिता। बच्चों को एक HTML संग्रह देता है, जो एक नोडलिस्ट नहीं है ...
फ्रेडो

3

चूंकि आप ES6 ( एरो फ़ंक्शंस ) की सुविधाओं का उपयोग कर रहे हैं , आप बस इस तरह से लूप के लिए भी उपयोग कर सकते हैं :

for(let child of [{0: [{'a':1,'b':2},{'c':3}]},{1:[]}]) {
  console.log(child)
}


Upvoted। क्या एक गर्भपात, ES6 सिंटैक्स, हालांकि ... मुझे रोना चाहता है, और मैं एक C ++ पृष्ठभूमि से आ रहा हूं ...
फ्रेडो

1

आप देख सकते हैं कि आप लिखकर foreach सही ढंग से, कि आप लिखकर foreach अन्य प्रोग्रामिंग भाषाओं यह काम नहीं करेगा में की तरह।


0

आप childNodesइसके बजाय उपयोग कर सकते हैं children, childNodesब्राउज़र संगतता समस्याओं पर भी अधिक विश्वसनीय है, यहाँ अधिक जानकारी :

parent.childNodes.forEach(function (child) {
    console.log(child)
});

या स्प्रेड ऑपरेटर का उपयोग करना:

[...parent.children].forEach(function (child) {
    console.log(child)
});
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.