vanila javascript 프로젝트를 하다가 "Array.prototype.slice.call()" 코드를 보았을 때 당황했지만,
무언가를 한 가지 더 배울 수 있다는 생각에 행복했습니다.
이 글은 해당 코드를 자세히 분석해보았으며 연관되어있는 코드/이론 또한 다루고 있습니다.
NodeList
<!-- html -->
<div class="item">0</div>
<div class="item">1</div>
<div class="item">2</div>
// js
let itemEls = document.querySelectorAll(".item");
console.log(itemEls)
// NodeList(3)[div.item, div.item, div.item]
콘솔로 itemEls를 찍어보면 " NodeList(3)[div.item, div.item, div.item] "이 찍힙니다.
배열과 비슷하게 생겼지만 배열은 아닙니다.
document.querySelectorAll와 같은 메서드에 의해 반환되는 노드 콜렉션입니다.
forEach()를 사용하여 반복할 수 있지만 프로젝트를 하다 보면 배열로 바꿔야 할 때가 있습니다.
방법은 여러가지가 있지만 일단은 Array.prototype.slice.call()를 사용하며 배열을 만드는 것을 일단 목표로 잡고 들어가겠습니다.
Array.prototype.slice.call()
let itemEls = document.querySelectorAll(".item");
itemEls = Array.prototype.slice.call(itemEls);
console.log(itemEls);
// [div.item, div.item, div.item]
위와 같이 Array.prototype.slice.call()을 사용하면 배열로 바뀌게 됩니다.
이제 하나씩 뜯어봅시다.
* Array -> 배열을 생성할 때 사용하는 리스트 형태의 고수준 객체입니다. (MDN)
* Array.prototype -> Array객체의 메서드를 prototype을 통하여 가져옵니다.
* Array.prototype.slice() -> begin부터 end까지 얕은 복사로 배열 객체를 반환합니다. (MDN)
slice MDN에서 주의 깊게 보셔야 할 부분이 아래 사진입니다.
1. slice()메서드를 호출해서 배열형 객체와 콜렉션을 새로운 Array로 변환
2. Function.prototype.call() 메서드를 사용해서 바인딩할 수 있다.
이 두 가지가 중요한 것 같은데요! 합쳐보면 이렇습니다.
slice를 통해서 새로운 Array를 변환하기 위하여 Function.prototype.call()으로 바인딩을 해주어야 합니다.
자 여기서 한 가지 알아보아야 할게 또 나왔습니다.
제가 생각하는 이글의 핵심은 여기 있습니다.
Function.prototype.call() -> 주어진 this값 및 전달된 인수와 함께 호출합니다.
call()을 사용하여 slice()에게 저희의 NodeList를 인자로 넘기는 것입니다.
전달받은 slice()는 최종적으로 원하는 배열을 만들어줍니다.
이렇게 저희가 처음 목표로 잡았던 유사 배열 객체 즉 NodeList나 arguments를 Array로 변환해 보았습니다.
한 발자국 더 나아가 코드를 간단하게 만들어보겠습니다.
Array.from, Spread Operator([...])
Array.from나 Spead Operator를 사용하면 Array.prototype.slice.call()과 같이 길게 사용하지 않아도 Array를 만들어줍니다.
두 방식은 어떻게 다른 걸까요?
먼저 Array.from의 경우 유사 배열 객체를 복사하기 위해 존재합니다. (MDN)
Spead Operator는 배열을 복사하고 병합하는 등 다양한 기능들을 수행하는데요. (MDN)
여기서 복사 기능으로 배열을 만들어줍니다.
위에서 언급한 복사는 유사 배열 객체를 배열로 만들어 주며,
얕은 복사(Shallow copy)라고 합니다.
자 그럼 여기서! 얕은 복사는 무엇일까요??
글이 너무 길어져서 다음 글에서 소개해드리겠습니다.
읽어주셔서 감사합니다!!
'Front-end > 깊게 파고들기' 카테고리의 다른 글
DOM Node, Element 정리 (0) | 2022.01.03 |
---|---|
Javascript 얕은복사, 깊은복사 (0) | 2021.12.26 |
CSR vs SSR (with TTI, TTV, SEO) (0) | 2021.12.16 |
양방향/단방향 데이터 바인딩 (0) | 2021.11.22 |
쿠키와 세션 (0) | 2021.11.20 |