[TIL] 유사배열과 call, apply, from

Simple Key·2021년 4월 29일
0

최근 오랜만에 바닐라 자바스크립트로 개발을 하게되었다.

프레임워크만 사용하다 바닐라 자바스크립트를 사용하니 나름 또 재미가 있다.

<!--html-->
<ul class="menu-container">
  <li></li>
  <li>회사소개</li>
  <li>서비스</li>
  <li>오시는길</li>
<ul>

대략 이렇게 메뉴 list가 있고 각 메뉴에 click 이벤트를 줘야하는 상황

일단 각 li에 접근해야하는데 메뉴마다 변수로 지정해서 접근하기에는 코드가 너무 길어질 수 있다.

let menuList = document.querySelectorAll('.menu-container li');

querySelectorAll을 사용하여 .menu-container의 자식 엘리먼트

  • 를 가져오기로 했다.

    console.log(menuList)
    //NodeList [li, li, li, li]

    [ ]로 쌓여있기 때문에 배열같아 보이지만 사실 배열이 아니다
    Array.isArray(menuList)로 확인해보면 false가 뜬다!

    그렇기 때문에 menuList에 map, filter, forEach같은 배열 메서드를 사용하려하면 에러가 발생한다.

    이럴때 메서드를 빌려 사용하기 위해 call, apply를 사용해야한다.

    let menuList = document.querySelectorAll('.menu-container li');
    menuList.forEach //error
    
    Array.prototype.forEach.call(menuList, function(menu){
    	menu.addEventListener('click', function(event){
    	//...이벤트 코드 생략...
      })  
    })

    이렇게 call을 사용하면 Array.prototype에서 forEach 메서드를 빌려 유사배열에도 사용할 수 있게된다. 이제 menulist의 각 li에 addEventListner를 붙이게 된 것!

    from

    또한 from을 사용하려면

    Array.from(menuList).forEach((menu) =>
      menu.addEventListener("click", function (event) {
        //...이벤트 코드 생략...
      })
    );
    

    이런식으로 사용 가능하다.

    call 과 apply

    let example = function(a, b, c){
       return a + b + c
    }

    위 example 함수를 호출하려면 보통 example 뒤에 ()를 붙여야 한다.
    다른 방법으로는 call과 apply를 사용하는 것이다.

    example(1, 2, 3) // 방법 1
    example.call(null, 1, 2, 3) // call를 이용하는 방법
    example.apply(null, [1, 2, 3])// apply를 이용하는 방법

    apply는 call과 다르게 인자를 배열로 묶어서 넣는다.
    그렇다면 여기서 null은 무엇인가?
    null은 this를 대체한다.

    let obj1 = { msg: 'hello', greeting: ()=>{ alert(this.msg)} };
    let obj2 = { msg: 'world'};
    
    obj1.greeting(); // 'hello';
    obj1.greeting.call(obj2); // 'world' 

    마지막 코드에서 obj1의 greeting이란 함수의 call메서드를 사용하니 greeting의 this가 obj1에서 obj2로 바뀌었다.

  • profile
    프론트엔드 개발자 심기현 입니다.

    0개의 댓글