카카오js 에서 call 오류가 납니다

마커를 클릭할때 커스텀 오버레이가 나타나는 구조인데 마커를 클릭할때마다 카카오js에서 call 언디파인 오류가 나서 해당 함수를 retrun function으로 감쌋습니다. 오류는 없어졌지만 처음 로드 됐을때 마커를 두번 클릭해야지만 커스텀 오버레이가 나타납니다.

코드를 봐야만 답변을 드릴 수 있을 것 같습니다.

현재 문서 페이지에 있는 샘플 코드 기준으로 마커를 클릭 했을 때 발생하는 오류는 없습니다.

현재 작성하신 코드로 봤을 때, 당연한 결과입니다.

  • kakao.maps.event.addListener의 세 번째 인자는 클릭 핸들러로써 사용할 함수를 넣어주는 것이 맞습니다.
    call 오류가 나는 이유는 함수가 아닌 값을 넣었기 때문입니다.

  • 하단의 이벤트 리스너만 사용하면 됩니다.
    현재 구조를 말로 설명해 드리면,

  1. 처음 마커를 클릭한다.
    1. markerClickEvent 함수가 리턴한 함수가 실행된다.
    2. markerClickEvent가 리턴한 함수는 마커에 클릭 이벤트를 등록한다.
      1. 등록만 되고 실행되지는 않는다.
    3. 결국 마커에 이벤트를 등록만하고 끝난 상태이므로 지도 위에는 아무것도 일어나지 않는다.
  2. 다시 마커를 클릭한다.
    1. 위의 1.1 ~ 1.3 이 다시 발생한다. (동일한 동작을 하는 이벤트 핸들러가 중복되서 걸린다.)
    2. 그리고나서 1.2번에서 등록되었던 핸들러가 실행된다.
  3. 다시 마커를 클릭한다.
    1. 다시 중복 이벤트가 걸리고
    2. 1과 2에서 중복해서 걸린 이벤트들이 두 번 순차적으로 발생한다.
  4. 클릭 할 때마다 이벤트는 중복 등록되고 중복 실행된다.
    1. 제일 안쪽 이벤트 핸들러(리턴되는 함수)에 로그를 찍는 코드를 넣으면 클릭 할때마다 출력되는 로그 갯수가 증가하는걸 볼 수 있음.
  • overlay.setMap(map)는 한 코드 블락 내에 여러 번 호출될 필요가 없습니다. 이미 지도에 오버레이가 보이는 상황에서 의미가 없습니다.

문서를 자세히 읽어 보시는게 도움이 될 듯합니다.
https://apis.map.kakao.com/web/documentation/#event_addListener

코드를 일부분만 첨부해 주시면 충분한 가이드를 해 드릴 수 없습니다.
코드 전문이거나 적어도 하나의 기능을 하는 온전한 프로시저 코드를 첨부해 주시는게 원하시는 답변을 얻는데 유리할 수 있습니다.
그리고 추가 질문에 대해서는 스크린샷이 아닌 직접 코드를 올려주시길 부탁드립니다.
저희가 검증을 하기 어렵습니다. ^^;

// 함수 호출을 한 리턴값을 받아 넣으신 겁니다.
// 리턴값이 함수라면 문제 없지만,
kakao.maps.event.addListener(marker, 'click', markerClickEvent(map, marker, overlay));

// ...
// ..
// .

// 그럼 이 함수에서 함수를 반환하고 있나요?
// 아닙니다. 아무것도 반환하고 있지 않습니다. 그래서 에러가 나고 있는 거죠.
function markerClickEvent(map, marker, overlay) {
    kakao.maps.event.addListener(marker, 'click', function() {
        if (clickedOverlay) {
            clickedOverlay.setMap(null);
        }
        overlay.setMap(map);
        clickedOverlay = overlay;
    });
}

그렇기 때문에 아래와 같이 변경하셔야 합니다.

// 이벤트를 두 번 등록할 필요 없습니다. 다음과 같이 하세요.
function markerClickEvent(map, overlay) { // 추가로 마커를 제어할 것이 아니라면 필요 없으니 빼도 됩니다.
    if (clickedOverlay) {
        clickedOverlay.setMap(null);
    }
    overlay.setMap(map);
    clickedOverlay = overlay;
}

그럼 왜 저기서 함수를 한 번 감쌌는지 궁금하실 수도 있는데
이를 설명 드리려 한다면 내용이 매우 길어집니다. 게시판 성격에 맞지도 않고요.

많은 라이브러리/프레임워크에서 사용하는 이벤트 시스템과 그 콜백 사용방식 전반에 대해 알아보시고
카카오 지도 API의 사용법과 비교해 보세요. 별반 다르지 않음을 느끼실 겁니다. 매우 보편화된 형태입니다.

  • var 로 선언한 변수와 반복문을 같이 썼을 때 부작용
  • 자바스크립트 스코프 전반에 대한 이해(block scope, function scope, global scope)
  • 일급 객체로서의 함수
  • 비동기 흐름 제어

에 대해서 알아보시고

또 다른 형태로 작성할 수 있는 IIFE,
아예 다른 해결책인 반복문과 let/const가 있으니 확인해 보세요.