최근 오랜만에 바닐라 자바스크립트로 개발을 하게되었다.
프레임워크만 사용하다 바닐라 자바스크립트를 사용하니 나름 또 재미가 있다.
<!--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을 사용하려면
Array.from(menuList).forEach((menu) =>
menu.addEventListener("click", function (event) {
//...이벤트 코드 생략...
})
);
이런식으로 사용 가능하다.
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로 바뀌었다.