카카오맵에서 발견한 스코프 예제

N·2023년 4월 28일
0

소스코드

//https://apis.map.kakao.com/web/sample/calculatePolylineDistance

// 선이 그려지고 있는 상태일 때 지도를 클릭하면 호출하여
// 클릭 지점에 대한 정보 (동그라미와 클릭 지점까지의 총거리)를 표출하는 함수입니다
function displayCircleDot(position, distance) {
  // 클릭 지점을 표시할 빨간 동그라미 커스텀오버레이를 생성합니다
  var circleOverlay = new kakao.maps.CustomOverlay({
    content: '<span class="dot"></span>',
    position: position,
    zIndex: 1,
  });

  // 지도에 표시합니다
  circleOverlay.setMap(map);

  if (distance > 0) {
    // 클릭한 지점까지의 그려진 선의 총 거리를 표시할 커스텀 오버레이를 생성합니다
    // let, const로 바꾸면 커스텀 오버레이가 교체되지 않는다
    var distanceOverlay = new kakao.maps.CustomOverlay({
      content:
        '<div class="dotOverlay">거리 <span class="number">' +
        distance +
        "</span>m</div>",
      position: position,
      yAnchor: 1,
      zIndex: 2,
    });

    // 지도에 표시합니다
    distanceOverlay.setMap(map);
  }

  // 배열에 추가합니다
  dots.push({ circle: circleOverlay, distance: distanceOverlay });
}

상황

카카오맵 예제는 전부 var를 사용하고 있다. var는 함수 스코프를 따르기 때문에 함수 안이면 블록을 벗어나도 선언 없이 변수에 값을 할당할 수 있고 할당된 값이 있다면 어디서든지 값을 사용할 수 있다.
circleOverlay, distanceOverlay는 재할당되는 변수가 아니기 때문에 const로 교체했는데 커스텀 오버레이가 교체되지 않는 문제가 발생하였다.

원인

circleOverlay는 var로 선언되었지만 함수의 가장 바깥에서 선언되었기 때문에 let, const로 교체해도 var로 선언한 것과 차이가 없었다.
그러나 distanceOverlay는 let이나 const로 교체하면 if문의 블록 스코프를 따르기 때문에 하단의 코드에서 dots 배열에 추가가 되지 않는다.

// 배열에 추가합니다
  dots.push({ circle: circleOverlay, distance: distanceOverlay });

따라서 let 또는 const로 선언을 하고 싶다면 스코프 바깥에서 let으로 선언한 뒤 내부에서 값을 할당하는 방법을 선택할 수 있다. 이 경우 const는 선언할 때 반드시 초기화를 해야하고 재할당을 할 수 없으므로 let을 사용할 수 있다

결과

  let distanceOverlay;
  if (distance > 0) {
    // 클릭한 지점까지의 그려진 선의 총 거리를 표시할 커스텀 오버레이를 생성합니다
    // let, const로 바꾸면 커스텀 오버레이가 교체되지 않는다
    distanceOverlay = new kakao.maps.CustomOverlay({
      content:
        '<div class="dotOverlay">거리 <span class="number">' +
        distance +
        "</span>m</div>",
      position: position,
      yAnchor: 1,
      zIndex: 2,
    });

    // 지도에 표시합니다
    distanceOverlay.setMap(map);
  }

  // 배열에 추가합니다
  dots.push({ circle: circleOverlay, distance: distanceOverlay });
profile
web

0개의 댓글