HTMLCollection vs NodeList 둘의 차이를 알고 있나요?

jangws·2022년 2월 24일
1

DOM

목록 보기
5/5
post-thumbnail

HTMLCollection vs NodeList

HTML의 구조나 내용 또는 스타일 등을 동적으로 조작할 필요가 자주 있는데, 이를 위해서는 먼저 요소 노드를 취득해야 한다.
같은 class 어트리뷰트 값을 갖는 모든 요소 노드들을 취득하기 위한 방법에는 두 가지가 있는데, querySelectorAllgetElementsByClassName이 바로 그것이다.
그런데 둘 다 같은 효과를 내는 것 같은데, 왜 두 개나 있는지 의문이 들었고 둘의 공통점과 차이점이 궁금해졌다. 특히, 습관적으로 Array.from()을 하여 유사배열객체를 배열로 만들어 왔는데 그 이유도 확실히 알아야겠다는 생각이 들었다.

HTMLCollection, NodeList 두 객체의 공통점

  • 둘 다 DOM API가 여러 개의 결과값을 반환하기 위한 DOM 컬렉션 객체이다.
  • 또한, 둘 다 유사 배열 객체이면서 이터러블이다.
    • 따라서 둘 다 for ...of 문으로 순회할 수 있다.
    • Array.from 메서드나 스프레드 연산자를 사용하여 배열로 만들 수 있다.
  • item() 메서드는 두 객체에 모두 있는 메서드다. 첫 번째 인자로 받는 index 값에 해당하는 아이템을 반환한다.

HTMLCollection

  • getElementsByTagName, getElementsByClassName 메서드를 통해 반환된다.
  • children 프로퍼티를 통해 반환된다.
    • children 프로퍼티가 반환하는 HTMLCollection 에는 텍스트 노드가 포함되지 않는다.
  • Live 객체이다.(객체가 스스로 실시간 노드 객체의 상태 변경을 반영한다)
    • Live 객체라는 특성 때문에, 반복문을 순회하다가 부작용이 발생할 수 있다.
      • 이에 대한 해결책은 for 문을 역방향으로 순회 하거나 while 문을 사용하여 객체에 노드 객체가 남아 있지 않을 때까지 무한 반복하는 방법등으로 회피할 수도 있다.
      • 더 간단한 해결책은 부작용의 원인인 HTMLCollection 객체를 사용하지 않고, 배열로 변환하는 것이다. 그러면 유용한 배열의 고차함수(forEach, map, filter, reduce 등)을 사용할 수 있다. 또는 querySelectorAll 메서드를 사용하여 NodeList 객체를 반환받아 사용할 수도 있다.
  • forEach() 메서드를 갖고 있지 않다.(배열로 만들어야 사용 가능)
  • 객체의 각 요소에는 배열의 인덱스로 접근하거나, 객체의 속성에 접근하듯이 .[속성명]의 방식으로 접근할 수도 있다.
  • HTMLCollection 객체에만 있는 메서드로는 namedItem()가 있다. 요소의 name 어트리뷰트의 값이 있는 경우에 이 메서드를 이용하여, namedItem()의 첫 번째 인자가 name 어트리뷰트의 값과 일치하는 요소를 반환한다.

NodeList

  • querySelectorAll 메서드를 통해 반환된다.
  • childNodes 프로퍼티를 통해 반환된다.
    • childNodes 프로퍼티가 반환한 NodeList에는 요소 노드뿐만 아니라 텍스트 노드도 포함되어 있을 수 있다.
  • 대부분 Non-live 객체이다(노드가 변경되어도 그 상태를 반영하지 않는다).
    • 다만, childNodes 프로퍼티는 live 객체이므로 주의가 필요하다.
  • forEach(), entries(), keys(), values() 메서드를 갖고 있다.(이외에 배열의 고차함수는 배열로 변환해야 사용 가능)

결론

이처럼 HTMLCollection이나 NodeList 객체는 예상과 다르게 동작할 때가 있어 다루기 까다롭고 실수할 수 있다. 또한, 각 객체마다 메서드를 어느 정도 제공하기는 하지만, 배열의 고차함수(forEach, map, filter, reduce 등)만큼 다양한 기능을 제공하진 않는다.

그러므로 노드 객체의 상태 변경과 상관없이 안전하게 DOM 컬렉션을 사용하고 유용한 고차함수를 사용하려면, HTMLCollection이나 NodeList 객체를 배열로 변환하여 사용하는 것이 좋다.

  • Array.from 메서드스프레드 연산자를 사용하여 간단히 배열로 변환할 수 있다.

0개의 댓글