여러개 마커 클릭 이벤트를 주었는데 마지막 마커에만 이벤트가 동작합니다

안녕하세요. 여러개 마커 클릭 이벤트를 주었습니다.
positions라는 이름의 array로 마커를 생성했고, 마커 클릭 시 positions의 title이라는 인포윈도우가 뜨도록 만들었는데요.
마커들의 위치는 제대로 생성되지만, 어떤 마커를 클릭해도 positions array의 마지막 element 위에 마지막 element의 title이 써진 인포윈도우만 생성됩니다. 어떻게 해결하나요?

var imageSrc = "http://t1.daumcdn.net/localimg/localimages/07/mapapidoc/markerStar.png";

for (var i = 0; i < positions.length; i ++) {

    // 마커 이미지의 이미지 크기 입니다
    var imageSize = new kakao.maps.Size(24, 35);

    // 마커 이미지를 생성합니다
    var markerImage = new kakao.maps.MarkerImage(imageSrc, imageSize);

    // 마커를 생성합니다
    var marker = new kakao.maps.Marker({
        map: map, // 마커를 표시할 지도
        position: positions[i].latlng, // 마커를 표시할 위치
        title : positions[i].title, // 마커의 타이틀, 마커에 마우스를 올리면 타이틀이 표시됩니다
        image : markerImage // 마커 이미지
    });

    // 인포윈도우
    var infowindow = new kakao.maps.InfoWindow({
        content: positions[i].title, // 인포윈도우에 표시할 내용
        removable : true
    });

    kakao.maps.event.addListener(marker, 'click', function() {
        console.log(positions[i].title);
        // 마커 위에 인포윈도우를 표시합니다
        infowindow.open(map, marker);
    });

}

marker들을 setMap 함수와 push 함수에 넣어서 배열로 관리해야하지 않을까요?

해당 함수는 카카오 예제에서 그대로 가져왔습니다~
http://apis.map.kakao.com/web/sample/multipleMarkerControl/

// 마커가 지도 위에 표시되도록 설정합니다
marker.setMap(map);
// 생성된 마커를 배열에 추가합니다
markers.push(marker);

1개의 좋아요

http://apis.map.kakao.com/web/sample/multipleMarkerEvent/

http://apis.map.kakao.com/web/sample/multipleMarkerEvent2/
에는 push를 하지 않아도 잘 동작하는데 이유가 뭘까요?

헛… 제가 안되는 부분에 대해 글을 제대로 못읽어보고 답변을 달았었네요ㅠㅠㅠ
제대로 글을 읽었어야했는데…

addListener 에 click 이벤트를 줄때
infowindow 를 넣어주고

/마커 클릭하면 인포윈도우/
kakao.maps.event.addListener(marker, ‘click’, makeClickListener(map, marker, infowindow));

/marker click event/
function makeClickListener(map, marker, infowindow) {
return function() {
infowindow.open(map, marker);
};
}

이렇게 작업하시면 나오는 것 같아요

즉시실행함수와 클로져 기법을 사용하여 핸들러를 생성하시거나
positions.forEach를 사용하여 스코프를 유지시켜주는 것이 핵심입니다.

자바스크립트의 for문 같은 경우에는
비동기 작업이나 이벤트 핸들링 같이 특정 시점 이후에 동작하는 행동을 기술하는 로직과 섞여버리면
각 루프마다 반복 참조하는 값에 대해서 의도치 않는 부작용이 나타날 수 있습니다.

위의 질문만 봐도,
이벤트 핸들러 내부에서 찍은 콘솔은 반복문이 모두 실행 된 이후
즉, i 값의 모든 증가가 끝난 시점에서 실행될 것이기 때문에
마지막 마커만 나오는게 맞습니다.

이는 자바스크립트에서 정상적인 상황이며
다른 언어와 더 친숙하시다면 언어의 설계 미스 라고 생각할 수 있는 상황일 겁니다.
언어적 특성이지 지도 API의 문제는 아니라는 것 인지해 주시고요.

다른 해결책으로는 var 대신 const, let을 사용하는 방법이 있습니다.
다만 이 방식은 구형 IE 대응이 힘들 수 있으니 참고 부탁드립니다.

답변 감사합니다!

아하 그렇군요. 그러면 @museforme 님이 남겨주신 답변도 @doji.doo 님의 답변의 원리와 같은 건가보네요.
자바스크립트는 잘 하지 않아서 발생했던 문제였나 봅니다 ㅠㅠ 감사합니다.
혹시 괜찮으시면 제 다른 질문도 봐주시면 정말 감사하겠습니다. 좋은 하루 되세요.

for (var i = 0; i < positions.length; i++) {
	// 마커를 생성합니다
	var marker = new kakao.maps.Marker({
		map : map, // 마커를 표시할 지도
		position : positions[i].latlng,
	// 마커의 위치
	});

	// 마커에 표시할 인포윈도우를 생성합니다 
	var infowindow = new kakao.maps.InfoWindow({
		content : positions[i].content,
		removeable : true
	// 인포윈도우에 표시할 내용
	});
	

	kakao.maps.event.addListener(marker, ‘click’, makeClickListener(map, marker, infowindow));

	function makeClickListener(map, marker, infowindow) {
	return function() {
	infowindow.open(map, marker);
	};
	}

}

이렇게 작업했는데도 마지막 마커에만 인포 윈도우가 뜨는거는 어떤게 잘못 일까요ㅜ