<!DOCTYPE html>
<html lang="en">
<head>
<title>Event</title>
</head>
<body>
<div class="testDiv"></div>
<div class="testDiv"></div>
<div class="testDiv"></div>
<div class="testDiv"></div>
<div class="testDiv"></div>
<script>
const querySelector = document.querySelectorAll('.testDiv');
const getElement = document.getElementsByClassName('testDiv');
console.log(querySelector);
console.log(getElement);
</script>
</body>
</html>
위와 같은 코드가 있다.
두 방식 중 어떤 것을 사용해도 div
태그 다섯 개를 찾아올 수 있다.
두 방식의 차이점은 무엇일까?
1. querySelectorAll
querySelectorAll
은 선택자에 일치하는 모든 요소를 반환한다.
이 때 반환하는 타입은 NodeList
다.
NodeList
는 노드의 컬렉션이라 한다.
NodeList
는 Array는 아니지만 forEach
등의 문법을 사용할 수 있다.
또한, Array.from
을 사용하여 Array로 변환할 수 있다.
하지만, NodeList
는 정적 콜렉션이다.
이는 DOM을 변경해도 콜렉션 내용에는 영향을 주지 않는다는 뜻이다.
따라서, 항목을 순회하거나 리스트의 길이를 캐시할 때 도움이 된다.
2. getElementsByClassName
getElementsByClassName
은 querySelectorAll
과 달리 HTMLCollection
을 반환한다.
HTMLCollection
은 NodeList와 달리 배열 메소드를 사용할 수 없으며 DOM의 변경이 실시간으로 반영된다.
3. 예제
위의 내용만 봤을 때는 어떤 차이가 있는지 이해하기 어렵다.
아래 예시를 보자.
VSC에서 사용 가능한 메소드를 확인해보면 NodeList
에 사용할 수 있는 메소드가 더 많은 것을 확인할 수 있다.
또한, NodeList의 경우 정적 콜렉션이라 했다.
아래와 같은 코드가 있을 때 실행 결과는 다음과 같다.
<!DOCTYPE html>
<html lang="en">
<head>
<title>Event</title>
</head>
<body id="body">
<div class="testDiv"></div>
<div class="testDiv"></div>
<div class="testDiv"></div>
<div class="testDiv"></div>
<div class="testDiv"></div>
<script>
const queryBefore = document.querySelectorAll('.testDiv');
const getBefore = document.getElementsByClassName('testDiv');
const body = document.getElementById('body');
const newDiv = document.createElement('div');
newDiv.classList.add('testDiv');
body.appendChild(newDiv);
const queryAfter = document.querySelectorAll('.testDiv');
const getAfter = document.getElementsByClassName('testDiv');
console.log(queryBefore.length); // 5
console.log(queryAfter.length); // 6
console.log(getBefore.length); // 6
console.log(getAfter.length); // 6
</script>
</body>
</html>
NodeList
와 달리 HTMLCollection
은 DOM의 변경이 반영되는 모습을 보여준다.
4. 여담
결과적으로 두 방식은 비슷한 듯 다르다.
데이터 타입에 대한 차이가 있으며 그에 따라 사용할 수 있는 메소드의 종류도 다르다.
배열처럼 생겼지만 배열의 모든 메소드를 사용할 수는 없다.
Array.from
등을 사용하여 두 방식 모두 배열 형태로 변경한 뒤 배열과 관련된 메소드를 사용할 수 있을 것이다.
또한, 속도적인 측면에서 getElementsByClassName
이 querySelectorAll
보다 빠르다고 한다.
하지만 querySelectorAll
방식은 ID와 CLASS를 동시에 선택자로 제공하는 등 더 복잡한 선택자를 사용할 수 있는 장점이 있다.
[참고자료]
Document: getElementsByClassName() method - Web APIs | MDN (mozilla.org)
Document: querySelectorAll() method - Web APIs | MDN (mozilla.org)
'개발 > JavaScript' 카테고리의 다른 글
[JavaScript] 커링(Currying) (0) | 2023.12.23 |
---|---|
[JavaScript] 클로저 (0) | 2023.09.16 |
[JavaScript] 이벤트 버블링과 캡처링 (0) | 2023.09.03 |
[JavaScript] addEventListener과 onclick의 차이 (0) | 2023.09.03 |
[NodeJS] 싱글 스레드와 이벤트 루프 (0) | 2023.07.29 |