중첩 객체 탐색

miyaongg·2023년 3월 13일
0
post-thumbnail

배열은 filter, forEach, find...등의 메소드로
배열 안에 원하는 값을 찾고 가져오고 했었는데,
중첩 객체인 경우 객체 안에 객체에서 원하는 값을 가져올 일이 생기니까
중첩 객체는 어떻게 탐색해야 하지...? 싶었다.


[ Todo ]
swiper.js의 swiper.realIndex와 미리 지정해둔 html의 data-index 속성을 비교해서 swiper의 현재 인덱스에 맞는 html요소를 노출시키는 것

[구현 방법]
1. swiperIdx 클래스를 가진 요소들을 탐색하여 저장
2. 저장된 요소들 중 현재 swipe의 index와 일치하는 data-index-number를 가진 요소를 탐색
3. 해당 요소에 show 클래스 추가
4. 나머지 요소에서는 show 클래스 제거


HTML

<div class="swiperIdx show" data-index-number="0">
  <div class="page_text">
    <div class="tit">Swipe 1</div>
    <div class="stit">첫 번째 Swipe입니다.</div>
  </div>
</div>
<div class="swiperIdx" data-index-number="1">
  <div class="page_text">
    <div class="tit">Swipe 2</div>
    <div class="stit">두 번째 Swipe입니다.</div>
  </div>
</div>
<div class="swiperIdx" data-index-number="2">
  <div class="page_text">
    <div class="tit">Swipe 3</div>
    <div class="stit">세 번째 Swipe입니다.</div>
  </div>
</div>
  • show 클래스로 div의 노출을 제어
  • data-index-number가 swiper.realIndex와 비교될 부분

  1. 우선 각 div의 data-index-number 값을 가져오기 위해 getElementsByClassName()을 사용해 swiperIdx 클래스가 들어간 요소들을 담았다.
const elements = document.getElementsByClassName('swiperIdx');
  • getElementsByClassName()은 HTMLCollection을 return한다.

    객체 안 객체 형태로 안에 요소에 어떻게 접근해야 할지 고민이 됐다..
    for...of 반복문으로 돌려서 안에서 비교하는 로직을 추가할까 하다가 지저분한 코드가 되는 것 같아 다른 방법을 찾아봤다.



  1. 2-1. 객체를 배열의 형태로 변환하는 Object.entries()의 사용
console.log(Object.entries(elements))

  • Object.entries() 메소는 객체를 [key, value] 쌍의 배열을 return한다.


    2-2. filter() 메소드를 사용해 swiper.realIndex와 일치하는 DOM 요소를 저장한다.
const item = (Object.entries(elements).filter(([ , elem]) => elem.dataset.indexNumber === swiper.realIndex.toString())[0])[1]

  1. 선택된 요소에 show 클래스를 추가한다.
item.classList.add('show')

이렇게 객체를 배열로 변환하여 탐색하는 방법으로 해결을 했다.
근데 정리하려고 찾아보다가 다른 방법도 발견해서 추가로 적어보자면

Array.prototype.filter.call

func.call(thisArg[, arg1[, arg2[, ...]]])

  • thisArg
    func 호출에 제공되는 this의 값.
  • return value
    this 와 arguments 를 매개로 호출된 함수의 반환값

    ** apply()와 차이점:
    call(): 인수 목록을, apply(): 인수 배열 하나를 받음
console.log(Array.prototype.filter.call(
  elements,
  (elem) => elem.dataset.indexNumber === "1"
))

const item = Array.prototype.filter.call(
  elements,
  (elem) => elem.dataset.indexNumber === swiper.realIndex.toString()
)[0]
  • call() 메소드는 주어진 this 값 및 각각 전달된 인수와 함께 함수를 호출
  • 배열 메소드를 유사배열(array-like object)에 적용시키고자 할 때 활용 가능
  • getElementsByClassName()로 반환된 HTMLCollection은 배열이 아니기때문에 filter() 메소드를 사용할 수 없는데, Array.prototype.filter.call()을 이용해 메소드를 먼저 기술하고 인자를 전달함으로써 filter() 메소드를 사용할 수 있다.




[참고: https://habitual-history.tistory.com/entry/JS-%EA%B0%9D%EC%B2%B4%EC%95%88%EC%97%90-%EA%B0%9D%EC%B2%B4%EC%97%90%EC%84%9C-%EC%9B%90%ED%95%98%EB%8A%94-%EA%B0%92%EB%A7%8C-%EA%B0%80%EC%A0%B8%EC%98%A4%EA%B8%B0-feat-entries-filter]

[참고: https://medium.com/@soyoung823/function-methods-c18bfe7923b]

profile
Front-End Developer

0개의 댓글