컬렉션의 내용을 반복하고 각 항목을 수동으로 배열에 넣는 것 외에 HTMLCollection을 배열로 변환하는보다 효율적인 방법이 있습니까?
Array.prototype.slice.call
하고 Brave (Chrome 59.0.3071 기반)는 여러 실행에 대한 두 자바 스크립트 테스트간에 거의 차이가 없습니다. 참조 jsperf.com/htmlcollection-array-vs-jquery-children
컬렉션의 내용을 반복하고 각 항목을 수동으로 배열에 넣는 것 외에 HTMLCollection을 배열로 변환하는보다 효율적인 방법이 있습니까?
Array.prototype.slice.call
하고 Brave (Chrome 59.0.3071 기반)는 여러 실행에 대한 두 자바 스크립트 테스트간에 거의 차이가 없습니다. 참조 jsperf.com/htmlcollection-array-vs-jquery-children
답변:
var arr = Array.prototype.slice.call( htmlCollection )
"네이티브"코드를 사용하는 것과 동일한 효과가 있습니다.
편집하다
이것은 많은 견해를 얻으므로 (@oriol의 의견에 따라) 다음과 같은 더 간결한 표현은 사실상 동등 하다는 점에 유의하십시오 .
var arr = [].slice.call(htmlCollection);
그러나 @JussiR의 의견에 따르면 "자세한"형식과 달리 프로세스에서 비어 있고 사용되지 않으며 실제로 사용할 수없는 배열 인스턴스가 생성된다는 점에 유의하십시오. 이것에 대해 컴파일러가하는 일은 프로그래머의 켄 외부에 있습니다.
편집하다
ECMAScript 2015 (ES 6)부터 Array.from 도 있습니다 .
var arr = Array.from(htmlCollection);
편집하다
ECMAScript 2015 는 기능적으로 동등한 스프레드 연산자를 제공합니다 Array.from
( Array.from
두 번째 인수로 매핑 기능 을 지원하는 경우도 있지만 ).
var arr = [...htmlCollection];
위의 두 가지 작업 모두에 대해 확인했습니다 NodeList
.
언급 된 방법에 대한 성능 비교 : http://jsben.ch/h2IFA
[].slice.call(htmlCollection)
도 작동합니다.
Array.from
즉 from
, IE11에서는 지원되지 않습니다.
이것이 가장 효율적인지 확실하지 않지만 간결한 ES6 구문은 다음과 같습니다.
let arry = [...htmlCollection]
편집 : Chris_F 의견의 또 다른 하나 :
let arry = Array.from(htmlCollection)
Array.from()
Array.from
즉 from
, IE11에서는 지원되지 않습니다.
나는 Array.prototype
일반적인 방법을 얻는 더 간결한 방법을 보았습니다 . HTMLCollection
객체를 객체로 변환하는 방법 Array
은 다음과 같습니다.
[] .slice.call (yourHTMLCollectionObject);
주석에서 언급했듯이 IE7 및 이전 버전과 같은 이전 브라우저의 경우 다음과 같은 호환성 기능을 사용해야합니다.
function toArray(x) {
for(var i = 0, a = []; i < x.length; i++)
a.push(x[i]);
return a
}
나는 이것이 오래된 질문이라는 것을 알고 있지만 받아 들여진 대답이 약간 불완전하다고 느꼈다. 그래서 나는 이것을 FWIW에 버릴 것이라고 생각했습니다.
크로스 브라우저 구현을 위해 prototype.js $A
함수 를 살펴볼 것입니다.
function $A(iterable) {
if (!iterable) return [];
if ('toArray' in Object(iterable)) return iterable.toArray();
var length = iterable.length || 0, results = new Array(length);
while (length--) results[length] = iterable[length];
return results;
}
Array.prototype.slice
모든 브라우저에서 사용할 수 없기 때문에 아마 사용하지 않습니다 . 폴 백이 자바 스크립트 루프이기 때문에 성능이 상당히 나쁩니다 iterable
.
$A
기능이 대부분의 시간에하는 일입니다.
이것은 여기의 정보 (이 스레드)를 기반으로하는 개인 솔루션입니다.
var Divs = new Array();
var Elemns = document.getElementsByClassName("divisao");
try {
Divs = Elemns.prototype.slice.call(Elemns);
} catch(e) {
Divs = $A(Elemns);
}
가레스 데이비스 (Gareth Davis)가 그의 직책에서 $ A를 묘사 한 곳 :
function $A(iterable) {
if (!iterable) return [];
if ('toArray' in Object(iterable)) return iterable.toArray();
var length = iterable.length || 0, results = new Array(length);
while (length--) results[length] = iterable[length];
return results;
}
브라우저가 가장 좋은 방법을 지원하면, 그렇지 않으면 크로스 브라우저를 사용합니다.
[,,]
됩니다 [undefined, undefined]
.
이전 IE 버전을 포함한 모든 브라우저에서 작동합니다.
var arr = [];
[].push.apply(arr, htmlCollection);
jsperf가 아직 작동하지 않기 때문에 여기에 여러 가지 방법의 성능을 비교하는 jsfiddle이 있습니다. https://jsfiddle.net/qw9qf48j/
var args = (htmlCollection.length === 1 ? [htmlCollection[0]] : Array.apply(null, htmlCollection));
효율적인 방식으로 배열과 같은 배열을 배열로 변환하기 위해 jQuery를 사용할 수 있습니다 makeArray
.
makeArray : 배열과 유사한 객체를 실제 JavaScript 배열로 변환합니다.
용법:
var domArray = jQuery.makeArray(htmlCollection);
약간의 추가 :
배열 객체에 대한 참조를 유지하지 않으려는 경우 (대부분의 HTMLCollection은 동적으로 변경되어 다른 배열로 복사하는 것이 더 좋습니다)이 예제에서는 성능에주의를 기울입니다.
var domDataLength = domData.length //Better performance, no need to calculate every iteration the domArray length
var resultArray = new Array(domDataLength) // Since we know the length its improves the performance to declare the result array from the beginning.
for (var i = 0 ; i < domDataLength ; i++) {
resultArray[i] = domArray[i]; //Since we already declared the resultArray we can not make use of the more expensive push method.
}
배열 형이란 무엇입니까?
HTMLCollection 은 "array-like"
객체이며, 배열과 유사한 객체는 배열의 객체와 유사하지만 많은 기능적 정의가 없습니다.
배열 같은 객체는 배열처럼 보입니다. 번호가 매겨진 요소와 길이 속성이 있습니다. 그러나 그것이 유사성이 멈추는 곳입니다. 배열과 같은 객체에는 Array의 기능이 없으며 for-in 루프는 작동하지 않습니다!
for (var a=[], i=collection.length; i;) a[--i] = collection[i];
그래서 "con"이 많지 않습니다 :-)