GRAMMAR

Writing
  • account_tree
  • bug_report

전역변수로서의 DOM 참조

들어가며

<!DOCTYPE html>
<html>
<head></head>
<body>
<button type="button" id="myButton">Click me</button>

<script type="text/javascript">
window.addEventListener("load", function() {
    myButton.onclick = () => alert("Clicked");
});
</script>
</body>
</html>

위와 같은 코드가 정상 작동할까?

놀랍게도 크롬(Chrome), 파이어폭스(Firefox), 사파리(Safari) 등의 대부분의 웹브라우저에서 제대로 동작한다. 사실 놀라울 필요도 없는 것이 위와 같은 코드 패턴이 표준이라는 것이다. 우리는 이 사실을 모르고 다음 아래와 같이 코드를 습관적으로 작성했다.

<!DOCTYPE html>
<html>
<head></head>
<body>
<button type="button" id="myButton">Click me</button>

<script type="text/javascript">
window.addEventListener("load", function() {
    var myButton = document.querySelector("#myButton");
    myButton.onclick = () => alert("Clicked");
});
</script>
</body>
</html>

쟁점은 작성된 마크업에 명시된 요소의 idname 속성 값을 이용하여 자바스크립트로 바로 사용할 수 있도록 전역 변수화 한다는 것이다.

이 방식은 원래부터 표준이 아니었다. 인터넷 익스플로러(Explorer)에서 적용했던 것이었고 다른 웹브라우저들이 호환성을 위해서 도입을 하게 되었다.

사실 DOM 처리를 위해서 매번 getElementById() 등의 API를 이용하는 것에 대한 불편함을 개선하고자 하는 결과물이기도 하다. 긍정적인 방식이라 여기게 되었고 무엇보다도 호환성을 고려해 다른 웹브라우저들도 수용을 하게 된 것이라 본다.

하지만 이러한 방식이 표준임에도 불구하고 회의적인 시각을 갖는 이유는 무엇일까?

왜 회의적인가?

전역 변수 체계를 혼란스럽게 할 수 있다.

사실 전역 변수를 사용하는 것을 자제하는 추세라고 본다면 당연히 바람직한 방향은 아니라고 본다. 왜 전역 변수를 자제하는지는 구지 이 글에서 구구절절 설명하지 않아도 경력이 있는 개발자라면 충분히 알고 있다.

변수 명 작성시 뒤죽박죽 상황이 벌어질 수 있다.

다음 아래의 코드는 DOM에 제시된 id를 무색하게 만들어 버린다.

<!DOCTYPE html>
<html>
<head></head>
<body>
<button type="button" id="myButton">Click me</button>

<script type="text/javascript">
var myButton;
window.addEventListener("load", function() {
    myButton = "Hello";
});
</script>
</body>
</html>

내장된 전역 프로퍼티와 충돌할 수 있다.

location, history 등과 같은 전역 프로퍼티는 분명히 자기 역할이 있지만 자칫 DOM의 식별 전역 변수로 오염될 수 있다.

<!DOCTYPE html>
<html>
<head></head>
<body>
<button type="button" id="history">Click me</button>

<script type="text/javascript">
window.addEventListener("load", function() {
    history.onclick = () => alert("Clicked");
});
</script>
</body>
</html>

name 속성은 모든 단일 요소를 대상으로 하지 않는다.

아래의 샘플 코드의 경우 form에 한해서 name 속성을 사용하고 있다. 따라서 myname.style.backgroundColor 코드는 에러를 만든다. 또한 이것은 웹브라우저 별 호환성 문제를 가질 수 있다.

결론

오늘날의 DOM은 한번 정해진 대로 남아있지 않는다. 변화무쌍하고 코드의 스케일도 매우 커졌다. 따라서 DOM에 정해진 식별값을 전역변수로 사용하는 것으로 가두어 버린다면 그렇지 않은 방법으로 사용해서 얻는 자유도를 포기하는 것일 수 있다.

명시적이라는 말은 매우 안정스럽다.  아래와 같은 훌륭한 API들을 사용하여 개발자가 명시적으로 대상을 선별해 나가는 방식으로 다양한 문제를 만들어 낼 확률을 줄이는 것이 더 나을 것이다.

  • getElementById()
  • getElementsByName()
  • getElementsByClassName()
  • getElementsByTagName()
  • querySelector()
  • querySelectorAll()

외부 리소스

DOM Element References as Global Variables
DOM 식별값인 id와 name 속성에 대한 자동 전역 변수화에 대한 입장