toggle-toggle / javascript-basic

🌱우아한 테크코스 프론트엔드 자바스크립트 기초 스터디 입니다.
9 stars 0 forks source link

[DOM & BOM] NodeList와 HTMLCollection에 대해 아는대로 설명해보세요. #20

Open Tanney-102 opened 3 years ago

shinsehantan commented 3 years ago

기본적으로 NodeList와 HTMLCollection은 모두 복수의 결과값을 반환하기 위한 node의 컬렉션 객체라는 점에서 공통점을 가집니다. 하지만 몇 가지 차이점이 있기 때문에 이를 중심으로 비교해보겠습니다. 우선, HTML Collection은 getElementsByTagName, getElementsByClassName 사용 시 리턴되는 형태입니다. TagName과 ClassName 모두 '복수'의 실행 결과를 리턴하기 때문에 HTML Collection인 것이며, getElementsById는 고유한 Id로 '단일'의 실행 결과를 리턴하기 때문에 HTML Collection이 아닌 HTML Elements인 것입니다. HTML Collection은 유사 배열이기 때문에 배열 객체에서 사용하는 메서드인 forEach는 사용할 수 없습니다. NodeList의 프로토타입에는 forEach, map이 없고, Array의 프로토타입에만 존재하기 때문입니다. Map을 사용하기 위해서는 Array.from(), Spread syntax 등을 이용해 사용할 수 있습니다. NodeList 객체는 일반적으로 element.childNodes와 같은 속성(property)과 document.querySelectorAll과 같은 메서드에 의해 반환되는 노드의 콜렉션입니다. NodeList도 Array가 아니지만, 프로토타입에 forEach()가 포함되어 있기 때문에 forEach를 사용할 수 있습니다. 하지만 역시 map, filter 등의 메서드를 사용할 수 없어서 Array.from() 등을 사용해 배열로 바꿔줘야 합니다. 그런데, Array.from은 IE에서는 사용할 수 없는데 그 때는 배열의 얕은 복사본을 새로운 배열 객체로 반환하는 slice를 이용하면 됩니다. 또 한 가지 차이점은 DOM의 변경 사항이 실시간으로 변경되냐, 그렇지 않느냐인데요. HTMLCollection은 라이브 컬렉션입니다. 엘리먼트 중 하나를 변화시키면 그 즉시 컬렉션에 반영됩니다. 그래서 요소 하나하나를 순회하며 무언가를 처리하는데, 이 과정에서 변화가 일어나 순회하는 기준에서 빠져나가게 되면 원하는 결과를 얻지 못하게 되거나 버그를 만날 가능성이 있습니다. 반면, document.querySelectorAll() 메소드에 의해 반환되는 NodeList는 정적(Static) 콜렉션인데요. static 이란 대응되는 새로운 요소가 페이지에 추가되더라도 리스트가 갱신되지 않는다는 뜻입니다. 따라서 DOM의 변경 사항이 실시간으로 반영되지 않습니다. 따라서, NodeList의 항목(items)을 순회(iterate)하거나, 특히 리스트의 길이를 캐시(cache)해야 할 때는 querySelectorAll을 사용하는 것이 좋습니다.

bucketHaneul commented 3 years ago

getElementsByClassName(), getElementsByTagName(), children 메소드의 반환값은 HTMLCollection(live) 객체입니다. 이는 반환값이 복수인 경우 HTMLElement의 리스트를 담아 반환하는 객체입니다. 배열과 비슷한 사용법을 가지지만 배열은 아닌 유사배열(array-like object) 이고, 실시간으로 Node의 상태 변경을 하는 라이브 컬렉션 입니다.

반면, querySelectorAll, childNodes 메소드의 반환값은 NodeList(non-live) 객체입니다. NodeList(non-live) 역시 유사 배열이지만, 실시간으로 Node의 상태 변경을 하지 않는 정적 콜렉션입니다.

Tanney-102 commented 3 years ago
  1. HTMLCollection

    • getElementsByTagName, getElementsByClassName의 반환값 혹은 엘리먼트의 children 프로퍼티로 얻을 수 있다.
    • 유사 배열이다. (forEach 불가능)
    • 엘리먼트만 취급한다. 즉, children프로퍼티를 통해 얻을 수 있는건 자식 엘리먼트로 제한된다.
    • live object이다.
    • namedItem 메서드를 사용할 수 있다.

      → 인덱스가 아는 name 어트리뷰트를 통해 엘리먼트에 접근할 수 있다.

  2. NodeList

    • querySelectorAll의 반환 값 혹은 엘리먼트의 childNodes 프로퍼티로 얻을 수 있다.
    • 유사 배열이지만 forEach를 사용할 수 있다.
    • 모든 노드를 포함한다. 즉, childNodes는 텍스트 노드도 포함한다.
    • childNodes는 live Object, querySelectorAll의 결과만 non-live이다.
devhyun637 commented 3 years ago

NodeListHTMLCollection 모두 리턴 값이 복수인 경우에 반환되는 객체다. 유사배열로 배열과 비슷한 사용방법을 가지고 있지만, 배열은 아니다. Array.from()을 사용하여 배열로 변환하여 사용하면 배열의 메소드를 사용할 수 있다.

NodeList

HTMLCollection

ddongule commented 3 years ago

NodeList 객체는 일반적으로 element.childNodes와 같은 속성(property)과 document.querySelectorAll 와 같은 메서드에 의해 반환되는 노드의 콜렉션입니다. NodeList가 Array 는 아니지만, forEach() 를 사용하여 반복할 수 있습니다. 또한 Array.from() 을 사용하여 Array 로 변환 할 수도 있습니다. DOM의 변경 사항을 정적으로 콜렉션에 반영합니다. 하지만 Node.childNodes는 실시간으로 반영합니다. HTML Collection : getElementsByTagNamegetElementsByClassName 사용 시 리턴되는 형태는 HTMLCollection 객체를 반환합니다. HTMLCollection 인터페이스는 요소의 문서 내 순서대로 정렬된 일반 컬렉션(arguments처럼 배열과 유사한 객체)을 나타내며 리스트에서 선택할 때 필요한 메서드와 속성을 제공합니다. 여기서 주의할 점은 HTMLCollection 은 배열과 유사한 객체 라는 것이라는 점입니다.. 배열 객체에서 데이터 순회 시 사용하는 forEach 같은 함수는 사용할 수 없습니다.

jum0 commented 3 years ago

HTMLCollection

NodeList