왜 forEach 메소드는 children 속성에 대해 동작하지 않을까?

2020. 11. 21. 23:45·시행착오

이벤트 핸들러 함수에서 어떠한 DOM 요소의 자식 요소들에 접근하기 위해서 .children 을 사용합니다.

const parentElement = document.querySelector('.parent');
console.log(parentElement.children)

parentElement.children.forEach(function (entry) {
  console.log(entry);
});

위에서 작성한 코드에서 parentElement.children 은 자식 DOM 요소들이 담긴 리스트를 반환하기 때문에, 당연히 배열의 forEach 메소드를 사용하여 각각의 요소에 접근하여 어떤 동작을 수행할 수 있을 것이라고 생각하였습니다.

하지만 다음과 같은 에러 메세지를 콘솔 창에 빨간 글씨로 출력합니다.

TypeError: document.querySelector('.parent').children.forEach is not a function

 

그 이유는, .children 속성은 배열이 아닌 HTML Collection을 값으로 가지고 있습니다. HTML Collection은 length 속성을 가지고 있는 배열처럼 생긴 객체입니다. 하지만 Array.prototype으로부터 상속받지 않기 때문에 배열이 아닙니다.

그렇더라도, forEach 메소드를 사용할 방법은 있습니다. 바로 HTML Collection을 배열로 변환해주는 것입니다.

// ES6 이전의 문법
const children = [].slice.call(document.getElementById(...).children);

// ES6 문법
const children = Array.from(document.getElementById(...).children);

// ES6 문법2
const children = [...document.getElementById(...).children];
[...document.getElementById(...).children].forEach(child => console.log(child));

이렇게 배열로 변환된 children 은 이제부터 forEach 메소드 사용이 가능합니다.

 

이외에도, 다른 방법을 발견하였는데 되도록 이 방법은 권장하지 않습니다.

NodeList.prototype.forEach = HTMLCollection.prototype.forEach = Array.prototype.forEach;

document.getElementById("niceParent").children.forEach(...)

위의 코드에서는 forEach가 이미 존재하더라도 무조건 각 prototype에 추가하고 있습니다. 따라서 비효율적인 코드입니다. 더 좋은 방법은 실제로 forEach 메소드가 prototype에 존재하지 않은 경우에만 추가하는 것입니다.

if (window.NodeList && !NodeList.prototype.forEach) {
   NodeList.prototype.forEach = Array.prototype.forEach;
}
if (window.HTMLCollection && !HTMLCollection.prototype.forEach) {
   HTMLCollection.prototype.forEach = Array.prototype.forEach;
}

 

출처 : 스택오버플로우 질문 : Why is forEach not working for children?

'시행착오' 카테고리의 다른 글

[MySQL] Alter Table 실행 도중 발생한 Connection Lost 에러 해결  (0) 2022.08.23
[JavaScript] 로컬에서 자바스크립트 모듈이 담긴 HTML 파일을 실행하면?  (0) 2020.11.21
'시행착오' 카테고리의 다른 글
  • [MySQL] Alter Table 실행 도중 발생한 Connection Lost 에러 해결
  • [JavaScript] 로컬에서 자바스크립트 모듈이 담긴 HTML 파일을 실행하면?
rondeveloper
rondeveloper
  • rondeveloper
    Ron's learning record
    rondeveloper
  • 전체
    오늘
    어제
    • 분류 전체보기 (99)
      • k8s (1)
      • AWS (1)
      • 리눅스 (3)
      • Docker (8)
      • 라이브러리 & 프레임워크 (14)
        • React (2)
        • NestJS (8)
        • Spring (0)
        • Django (3)
        • FastAPI (1)
      • 웹 (2)
        • Nginx (1)
      • 프로그래밍 언어 (29)
        • HTML (0)
        • CSS (0)
        • JavaScript (21)
        • Python (3)
        • Node.js (0)
        • TypeScript (4)
        • Java (1)
      • Today I learned (9)
      • 알고리즘 (9)
        • 백준 (0)
        • 프로그래머스 (8)
        • 개념 (1)
      • 티끌모아 태산 (5)
        • 하루에 영단어 하나씩 (5)
        • 독서 (0)
      • 시행착오 (3)
      • 데이터베이스 (2)
        • MySQL (0)
      • 컴퓨터 과학 (8)
        • 네트워크 (2)
        • 운영체제 (0)
        • 데이터베이스 (2)
        • 자료구조 (4)
      • 포트폴리오 (4)
        • JJINCAFE IN SEOUL (4)
        • CODEUNICORN (0)
      • 회고 (0)
      • CICD (1)
  • 블로그 메뉴

    • 홈
    • 태그
    • 방명록
  • 링크

  • 공지사항

  • 인기 글

  • 태그

    mysql
    배열
    Docker
    쿠버네티스
    django
    도커
    모듈
    typescript
    기초
    코딩테스트
    스택
    컨테이너
    Kubernetes
    javascript
    조인
    리눅스
    redis
    nestjs
    네트워크
    자바스크립트
    Kubectl
    Til
    생활코딩
    iterable
    Python
    IP 주소
    프로그래머스
    레벨2
    typeorm
    FastAPI
  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.5
rondeveloper
왜 forEach 메소드는 children 속성에 대해 동작하지 않을까?
상단으로

티스토리툴바