web-dev-qa-db-fra.com

forEach n'est pas une erreur de fonction avec un tableau JavaScript

J'essaie de faire une boucle simple:

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

Mais j'obtiens l'erreur suivante:

VM384: 53 TypeError non capturé: parent.children.forEach n'est pas une fonction

Même si parent.children enregistre:

 enter image description here

Quel pourrait être le problème?

Remarque: Voici un JSFiddle .

56
alexchenco

Le parent.children est un objet semblable à un tableau. Utilisez la solution suivante:

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

Le parent.children est du type NodeList, qui est un objet semblable à un tableau car:

  • Il contient la propriété length, qui indique le nombre de nœuds
  • Chaque nœud est une valeur de propriété avec un nom numérique, commençant à 0: {0: NodeObject, 1: NodeObject, length: 2, ...}

Voir plus de détails dans cet article .

59
Dmitri Pavlutin

parent.children n'est pas un tableau. C'est HTMLCollection et il n'a pas de méthode forEach. Vous pouvez d'abord le convertir dans le tableau. Par exemple dans ES6:

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

ou en utilisant un opérateur de propagation:

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

parent.children renverra une liste de nœuds, techniquement un élément HTML Collection. C'est un tableau comme un objet, mais pas un tableau, vous ne pouvez donc pas appeler directement des fonctions de tableau par dessus. Dans ce contexte, vous pouvez utiliser Array.from() pour convertir cela en un tableau réel,

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

Une version plus naïve, du moins vous êtes sûr que cela fonctionne sur tous les appareils, sans conversion ni ES6:

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

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

7
Jean

parent.children est une HTMLCollection qui est un objet semblable à un tableau. Tout d’abord, vous devez le convertir en une vraie variable Array pour pouvoir utiliser les méthodes Array.prototype.

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

C'est parce que parent.children est un NodeList , et qu'il ne supporte pas la méthode .forEach (comme NodeList est un tableau semblable à une structure mais pas à un tableau), essayez donc de l'appeler en le convertissant d'abord en tableau à l'aide de

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

Si vous essayez de boucler sur une NodeList comme ceci:

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

Je recommande fortement la boucle de cette façon:

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

Personnellement, j'ai essayé plusieurs méthodes, mais la plupart d'entre elles ne fonctionnaient pas car je voulais boucler une NodeList, mais celle-ci fonctionne à merveille, essayez-la!

La NodeList n'est pas un tableau, mais nous le traitons comme un tableau, en utilisant Array.. Vous devez donc savoir qu'il n'est pas pris en charge par les anciens navigateurs!

Besoin de plus d'informations sur NodeList? Veuillez lire sa documentation sur MDN .

3
Elharony

Puisque vous utilisez les fonctionnalités de ES6 (fonctions arrow ), vous pouvez également utiliser simplement une boucle for comme ceci:

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

2
Armfoot

Pas besoin de la forEach, vous pouvez effectuer une itération en utilisant uniquement le second paramètre de from , comme suit:

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

2
Armfoot

Cela a toujours fonctionné pour moi

const someElement = document.querySelectorAll('.someElement');

  someElement.forEach((element) => {
    // Your code here
  });
0
King James Enejo