forEach는 JavaScript 배열에서 함수 오류가 아닙니다.


145

간단한 루프를 만들려고합니다.

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

그러나 다음과 같은 오류가 발생합니다.

VM384 : 53 Uncaught TypeError : parent.children.forEach는 함수가 아닙니다

parent.children로그 에도 불구하고 :

여기에 이미지 설명을 입력하십시오

무엇이 문제 일 수 있습니까?

참고 : 다음은 JSFiddle 입니다.


element.siblings와 동일한 문제가 발생합니다
— Daut

element.siblings가 HTMLCollection을 반환하고 HTMLCollections에 forEach () 메소드가 없기 때문에 @Daut 예
— Freddo

1
이봐, 구글 검색기! 이 더블 체크를 읽는다면 foreach 대신 E가 대문자로되어 있는지 확인하십시오.
— Robert Sinclair

답변:


127

첫 번째 옵션 : forEach를 간접적으로 호출

은 parent.children객체와 같은 배열입니다. 다음 해결책을 사용하십시오.

const parent = this.el.parentElement;

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

parent.childrenIS의 NodeList객체 때문에 같은 배열 인 유형 :

  • 그것은 포함 length노드 수를 나타내는 특성
  • 각 노드는 0부터 시작하는 숫자 이름의 특성 값입니다. {0: NodeObject, 1: NodeObject, length: 2, ...}

이 기사 에서 자세한 내용을 참조하십시오 .


두 번째 옵션 : 반복 가능한 프로토콜 사용

parent.children는 HTMLCollection: 어떤 구현하는 반복 가능한 프로토콜을 . ES2015 환경에서는 HTMLCollectioniterables를 허용하는 모든 구성과 함께 사용할 수 있습니다 .

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이 그것이 nodeList임을 알려주도록 사용할 브라우저. Firefox에서는 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
이 솔루션은 Array 프로토 타입을 망쳐 놓는 것보다 훨씬 더 좋습니다.
— Daut

그리고이 답변은 OPs 질문에 대한 정답입니다. parent.children는 .forEach 방법이 없습니다 HTMLCollection입니다
— Freddo

18

parent.children기술적으로 html Collection 인 노드 목록 목록 을 반환합니다 . 그것은 객체와 같은 배열이지만 배열은 아니므로 직접 배열 함수를 호출 할 수 없습니다. 이러한 맥락에서이를 실제 배열로 변환하는 데 사용할 수 있습니다 .Array.from()

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

아니, parent.children은 nodeList가 아니라 HTML Collection을 반환합니다. 같은 것이 아닙니다. 그것이 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
아니면 변환하지 않지만 .forEach ()에서 .call ()을 사용합니까?
— nnnnnn

@nnnnnn 아래 답변을 참조하십시오.
— Dmitri Pavlutin

배열에 객체 배열과 같은 변환하는 방법은 여러 가지가 있습니다 :)이 그것의 하나입니다
— 드미트리

@DmitriyLoskutov 변환 할 필요가 없습니다. JavaScript는 오리 입력 언어입니다. 이 기능을 사용하십시오.
— Dmitri Pavlutin

5

그 때문에 parent.childrenA는 NodeList를 , 그리고 상기지지 않는다 .forEach(NodeList의 구조가 아니라 배열처럼 배열이기 때문에) 따라서, 첫번째 방법을 사용하여 배열로 변환하여 호출 할

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

아니요, NodeList가 아니며 HTML 모음입니다
— Freddo

5

의 필요forEach 는 없으며 다음 from과 같이의 두 번째 매개 변수 만 사용하여 반복 할 수 있습니다 .

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


슬픈 소식은 parent.children이 nodeList가 아닙니다 ... .from ()이 작동하지 않는다는 것입니다.
— Freddo

@Cedric 객체가 NodeList가 아닌 경우이를 해결하기 위해 특별히 새로운 질문을해야합니다. 여기서 다운 보팅은 답이 본질적으로 잘못되었거나 해로운 경우에 사용되며 코드 스 니펫에서 볼 수 있듯이 객체의 모든 요소가 반복되고 인쇄됩니다. 이는 OP의 질문의 목표였습니다.
— Armfoot

그러나 문제는 OP의 질문이 nodeList가 아닌 HTML Collection과 관련되어 있다는 것입니다. 그래서 대답은 단순히 질문에 대답하지 않았습니다
— Freddo

@Cedric이 답변은 Array.from첫 번째 매개 변수에 제공된 객체를 배열로 변환하기 때문에 HTML 컬렉션을 반복 합니다. 결과는 추가 루프 ( MDN 문서) 가 필요없는 madox2의 답변 과 동일 합니다. forEachArray.from
— Armfoot

4

다음 NodeList과 같이 반복하려고 하면 :

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

이런 식으로 루프하는 것이 좋습니다.

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

개인적으로, 나는 여러 가지 방법을 시도했지만 대부분을 반복하고 싶었으므로 대부분 작동하지 않았습니다. NodeList 매력적 시도해보십시오!

은 NodeList배열이 아니라 우리가 사용하는 배열로 취급Array. 그래서, 당신은이 오래된 브라우저에서 지원되지 않는다는 것을 알아야합니다!

에 대한 자세한 정보가 필요하십니까 NodeList? MDN에 대한 설명서를 읽으십시오 .


1
이 답변은 분명히 nodeList에서 작동합니다. 문제는 parent.children이 nodeList가 아닌 HTML Collection을 반환한다는 것입니다.
— Freddo

3

ES6의 기능 ( 화살표 기능 )을 사용하므로 다음과 같이 for 루프 를 사용할 수도 있습니다 .

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


공감. ES6 구문이 얼마나 엉망입니까? 울고 싶고 C ++ 배경에서 왔습니다 ...
— Freddo

1

사용자가 입력하면 확인할 수 있습니다 대해 forEach를 올바르게 입력 한 경우, foreach 문을 작동하지 않습니다 다른 프로그래밍 언어처럼.


0

당신이 사용할 수있는 childNodes대신에 children, childNodes또한 브라우저 호환성 문제, 추가 정보를 고려하고 더 신뢰할 여기를 :

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

또는 스프레드 연산자 사용 :

[...parent.children].forEach(function (child) {
    console.log(child)
});
당사 사이트를 사용함과 동시에 당사의 쿠키 정책과 개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.