[javascript] ES6에서 노드 목록 필터링 또는 매핑

ES6에서 노드 목록을 필터링하거나 매핑하는 가장 효율적인 방법은 무엇입니까?

내 측정 값에 따라 다음 옵션 중 하나를 사용합니다.

[...nodelist].filter

또는

Array.from(nodelist).filter

어느 것을 추천 하시겠습니까? 예를 들어 어레이를 사용하지 않는 더 좋은 방법이 있습니까?



답변

  • [...nodelist] 객체가 반복 가능한 경우 객체에서 배열을 만듭니다.
  • Array.from(nodelist)객체가 반복 가능 하거나 객체가 배열과 같은 경우 (has .length및 numeric props) 객체에서 배열을 만듭니다.

NodeList.prototype[Symbol.iterator]두 경우 모두 iterable을 다루기 때문에 두 예제가 있으면 동일합니다 . 그러나 환경 NodeList이 반복 가능 하도록 구성되지 않은 경우 첫 번째 예제는 실패하고 두 번째 예제는 성공합니다. Babel현재이 사건을 제대로 처리하지 못하고 있습니다 .

그래서 당신 NodeList이 반복 가능 하다면 , 당신이 사용하는 것은 당신에게 달려 있습니다. 나는 사례별로 선택할 것입니다. 한 가지 이점은 Array.from매핑 함수의 두 번째 인수를 사용하는 반면 첫 번째 [...iterable].map(item => item)는 임시 배열을 만들어야하지만 Array.from(iterable, item => item)그렇지 않다는 것입니다. 그러나 목록을 매핑하지 않는 경우에는 중요하지 않습니다.


답변

TL; DR;

Array.prototype.slice.call(nodelist).filter

slice () 메서드는 배열을 반환합니다. 반환되는 배열 회수 (NodeList의)의 얕은 복사는 것을
이보다 더 빨리 작동 그래서 Array.from ()
가 최대한 빨리 작동 그래서 ) (Array.from

원본 컬렉션의 요소는 다음과 같이 반환 된 배열에 복사됩니다.

  • 객체 참조 (실제 객체가 아님)의 경우 slice는 객체 참조를 새 배열로 복사합니다. 원래 배열과 새 배열은 모두 동일한 객체를 참조합니다. 참조 된 객체가 변경되면 변경 사항이 새 배열과 원래 배열 모두에 표시됩니다.
  • 문자열, 숫자 및 부울 (String, Number 및 Boolean 객체가 아님)의 경우 slice는 값을 새 배열에 복사합니다. 한 배열에서 문자열, 숫자 또는 부울을 변경해도 다른 배열에는 영향을주지 않습니다.

인수에 대한 간단한 설명

Array.prototype.slice (beginIndex, endIndex)

  • 선택적 인수 beginIndex 및 endIndex를 사용합니다. 슬라이스가 제공되지 않으면 beginIndex == 0을 사용하므로 컬렉션에서 모든 항목을 추출합니다.

Array.prototype.slice.call (네임 스페이스, beginIndex, endIndex)

  • 개체를 첫 번째 인수로 사용합니다. 컬렉션을 객체로 사용하는 것은 문자 그대로 해당 객체 네임 스페이스 에서 직접 slice 메서드를 호출한다는 것을 의미합니다.


답변

NodeList에서 직접 사용 하는 참조 를 찾았습니다.map

Array.prototype.map.call(nodelist, fn)

나는 그것을 테스트하지 않았지만 NodeList에 직접 액세스해야하기 때문에 이것이 더 빠를 것입니다.


답변

이것은 어떤가요:

// Be evil. Extend the prototype.
if (window.NodeList && !NodeList.prototype.filter) {
  NodeList.prototype.filter = Array.prototype.filter;
}

// Use it like you'd expect:
const noClasses = document
  .querySelectorAll('div')
  .filter(div => div.classList.length === 0)

NodeList.forEach ( ‘Polyfill’아래) 에 대한 MDN 문서 에서 언급 한 것과 동일한 접근 방식 이며 IE11 , Edge, Chrome 및 FF에서 작동합니다.


답변