Array.from()
getElementsByClassName, getElementsByTagName 로 선언한 변수는 HTML Collection이라는 DOM을 반환한다.
선언한 셀렉터들에 클래스명을 변경하는 반복문을 돌린다고 가정했을 때,
<style>
.red {color:red}
.blue {color:blue}
</style>
<ul>
<li class="red">item1</li>
<li class="red">item1</li>
<li class="red">item1</li>
</ul>
let items = document.getElementsByClassName('red')
console.log(items) //HTMLCollection(3) [li.red, li.red, li.red]
for(let i=0; i<items.length; i++){
items[i].className = 'blue'
console.log(items) //HTMLCollection(2) [li.red, li.red] ==> 첫번째 li가 .blue를 가지게 되면서 요소에서 삭제되는 문제
}
i=1인 상황에서 기존의 0번째 요소가 컬렉션에서 삭제되게 된다. 즉 HTML Collection은 실시간 감지를 한다는 것이다.
따라서 의도치 않게 다른 결과를 도출할 수 가 있기 때문에, Array.from을 이용해서 배열객체로 변환 후 사용하는 것이 안전하다.
let items = document.getElementsByClassName('red')
console.log(items) //HTMLCollection(3) [li.red, li.red, li.red]
let itemsArr = Array.from(items)
console.log(itemsArr) //(3) [li.red, li.red, li.red]
for(let i=0; i<itemsArr.length; i++){
itemsArr[i].className = 'blue'
}
Array.from() 은 문자열 등 유사 배열(Array-like) 객체나 이터러블한 객체를 배열로 만들어주는 메서드
(※ 유사 배열 객체란, 키가 인덱스 값으로 되어있고 길이를 나타내는 length 속성을 갖는 객체를 의미합니다. ex 문자열변수)
getElementsByClassName, getElementsByTagName은 HTMLCollection 이라는 DOM 컬렉션을 반환.
querySelectorAll은 NodeList 라는 DOM 컬렉션을 반환합니다.
HTMLCollection은 노드의 상태 변화를 실시간으로 감지하고, NodeList는 노드를 정적으로 관리합니다.
다만 childNodes 가 리턴한 NodeList는 정적임이 보장되지 않습니다.
따라서, HTMLCollection 또는 NodeList를 그대로 사용할 때는 부작용 예방 차원 및 고차 함수 지원을 위해 Array 로 치환해 사용할 것을 권장
아래에서 참고했습니다.
https://merrily-code.tistory.com/212
HTMLCollection과 NodeList, 너흰 누구니?
바닐라 자바스크립트를 활용해 DOM에 접근할 때는 HTMLCollection, NodeList 등의 DOM 요소들의 컬렉션을 다루게 될 때가 있는데요, 이번 글을 통해 두 컬렉션의 성질을 간단히 알아보도록 하겠습니다. HT
merrily-code.tistory.com