제퍼넷 로고

명명된 요소 ID는 JavaScript 전역으로 참조할 수 있습니다.

시간

ID가 있는 DOM 요소는 JavaScript에서 전역 변수로 액세스할 수 있다는 사실을 알고 계셨습니까? 그것은 영원히 존재해 왔던 것들 중 하나지만 실제로 처음으로 파헤치는 것입니다.

이 소식을 처음 듣는 분이라면 안심하세요! HTML의 요소에 ID를 추가하기만 하면 작동하는 것을 볼 수 있습니다.

일반적으로 다음을 사용하여 새 변수를 정의합니다. querySelector("#cool") or getElementById("cool") 해당 요소를 선택하려면:

var el = querySelector("#cool");

그러나 우리는 실제로 이미 #cool 그 리가모랄 없이:

그래서, 어떤 id — 또는 name 속성, 그 문제에 대해 — HTML에서 다음을 사용하여 JavaScript에서 액세스할 수 있습니다. window[ELEMENT_ID]. 다시 말하지만, 이것은 정확히 "새로운" 것은 아니지만 실제로 보기 드문 일입니다.

짐작할 수 있듯이 명명된 참조를 사용하여 전역 범위에 액세스하는 것은 좋은 아이디어가 아닙니다. 어떤 사람들은 이것을 "글로벌 범위 오염자"라고 부르게 되었습니다. 그 이유에 대해 알아보겠습니다. 하지만 먼저…

일부 상황

이 접근법은 HTML 사양에 설명된, 여기서 "명명된 액세스 Window 물체."

Internet Explorer는 이 기능을 최초로 구현했습니다. 다른 모든 브라우저도 추가했습니다. Gecko는 당시 표준 모드에서 직접 지원하지 않는 유일한 브라우저였으며 대신 실험적인 기능으로 선택했습니다. 시행에 대한 망설임은 전혀 없었지만, 브라우저 호환성이라는 이름으로 앞서갔습니다. (Gecko는 심지어 웹킷을 설득하다 표준 모드에서 벗어나기 위해) 결국 Firefox 14에서 표준 모드로 만들었습니다.

잘 알려지지 않았을 수 있는 한 가지는 생성된 전역이 웹 페이지를 손상시키지 않도록 브라우저가 몇 가지 예방 조치를 취해야 한다는 것입니다. 그러한 조치 중 하나는…

가변 섀도잉

아마도 이 기능의 가장 흥미로운 부분은 명명된 요소 참조가 기존 전역 변수 그림자. 따라서 DOM 요소에 id 이미 전역으로 정의되어 있으면 기존 것을 재정의하지 않습니다. 예를 들어:


  
    window.foo = "bar";
  


  
I won't override window.foo
console.log(window.foo); // Prints "bar"

그리고 그 반대도 마찬가지입니다.

I will be overridden :(
window.foo = "bar"; console.log(window.foo); // Prints "bar"

이 동작은 다음과 같은 위험한 재정의를 무효화하기 때문에 필수적입니다.

, 그렇지 않으면 무효화하여 충돌이 발생합니다. alert API. 이 보호 기술은 당신이 나 같은 사람이라면 처음으로 이에 대해 배우는 이유일 것입니다.

명명된 전역에 대한 사례

앞서 나는 전역 명명된 요소를 참조로 사용하는 것이 가장 좋은 아이디어가 아닐 수도 있다고 말했습니다. 많은 이유가 있는데, 그 이유는 TJ VanToll이 블로그에서 잘 다루었습니다. 여기에서 요약하겠습니다.

  • DOM이 변경되면 참조도 변경됩니다. 그것은 정말로 "취약한"(사양의 용어 그것을 위해) HTML과 JavaScript 사이의 관심사의 분리가 너무 많이 될 수 있는 코드.
  • 우연한 참조는 너무 쉽습니다. 간단한 오타가 명명된 전역을 참조하게 되어 예기치 않은 결과를 초래할 수 있습니다.
  • 브라우저에서 다르게 구현됩니다. 예를 들어, 다음을 사용하여 앵커에 액세스할 수 있어야 합니다. id — 예 — 그러나 일부 브라우저(즉, Safari 및 Firefox)는 ReferenceError 콘솔에서.
  • 그것은 당신이 생각하는 것을 반환하지 않을 수 있습니다. 사양에 따르면 DOM에 동일한 명명된 요소의 인스턴스가 여러 개 있는 경우(예:

    — 브라우저는 다음을 반환해야 합니다. HTMLCollection 인스턴스의 배열로. 그러나 Firefox는 첫 번째 인스턴스만 반환합니다. 그럼 다시, 사양 말한다 우리는 하나의 인스턴스를 사용해야합니다 id 어쨌든 요소의 트리에서. 그러나 그렇게 하면 페이지가 작동하거나 이와 유사한 것이 중지되지 않습니다.

  • 아마도 성능 비용이 있습니까? 내 말은, 브라우저는 참조 목록을 만들고 유지해야 합니다. 몇 사람이 테스트를 실행했습니다. 이 StackOverflow 스레드에서, 여기서 명명된 전역 변수는 실제로 한 번의 테스트에서 더 높은 성능최근 테스트에서 성능이 떨어짐.

추가 고려 사항

명명된 전역 사용에 대한 비판을 버리고 어쨌든 사용한다고 가정해 보겠습니다. 전부다 괜찮아. 하지만 그렇게 하는 동안 고려해야 할 몇 가지 사항이 있습니다.

폴리 필

엣지 케이스처럼 들릴 수 있지만 이러한 유형의 전역 검사는 폴리필에 대한 일반적인 설정 요구 사항입니다. 새로운 쿠키를 사용하여 쿠키를 설정한 다음 예를 확인하십시오. CookieStore API, 아직 지원하지 않는 브라우저에서 폴리필:


  
  
    // Polyfill the CookieStore API if not yet implemented.
    // https://developer.mozilla.org/en-US/docs/Web/API/CookieStore
    if (!window.cookieStore) {
      window.cookieStore = myCookieStorePolyfill;
    }
    cookieStore.set("foo", "bar");
  

이 코드는 Chrome에서는 완벽하게 작동하지만 Safari에서는 다음 오류가 발생합니다.

TypeError: cookieStore.set is not a function

Safari는 다음을 지원하지 않습니다. CookieStore 이 글을 쓰는 시점의 API. 결과적으로 polyfill이 적용되지 않습니다. img 요소 ID는 다음과 충돌하는 전역 변수를 생성합니다. cookieStore 글로벌

자바스크립트 API 업데이트

상황을 뒤집고 브라우저의 JavaScript 엔진에 대한 업데이트가 명명된 요소의 전역 참조를 손상시킬 수 있는 또 다른 문제를 찾을 수 있습니다.

예 :


  
  
    window.BarcodeDetector.focus();
  

해당 스크립트는 입력 요소에 대한 참조를 잡고 다음을 호출합니다. focus() 그 위에. 제대로 작동합니다. 그래도 우리는 방법을 모릅니다 계속 작동합니다.

입력 요소를 참조하는 데 사용하는 전역 변수는 브라우저가 지원을 시작하자마자 작동을 멈춥니다. BarcodeDetector API. 그 시점에서, window.BarcodeDetector global은 더 이상 입력 요소에 대한 참조가 아니며 .focus() "를 던질 것이다.window.BarcodeDetector.focus 함수가 아닙니다." 오류입니다.

보너스: 명명된 모든 요소가 전역 참조를 생성하는 것은 아닙니다.

재미있는 것을 듣고 싶습니까? 부상에 대한 모욕을 더하기 위해 이름에 문자만 포함된 경우에만 명명된 요소에 전역 변수로 액세스할 수 있습니다. 브라우저는 다음과 같이 특수 문자와 숫자가 포함된 ID가 있는 요소에 대한 전역 참조를 생성하지 않습니다. hello-worlditem1.

결론

여기까지 온 방법을 요약하자면 다음과 같습니다.

  • 모든 주요 브라우저는 자동으로 각 DOM 요소에 대한 전역 참조를 생성합니다. id (또는 경우에 따라 name 속성).
  • 전역 참조를 통해 이러한 요소에 액세스하는 것은 신뢰할 수 없고 잠재적으로 위험합니다. 사용 querySelector or getElementById 대신.
  • 전역 참조는 자동으로 생성되기 때문에 코드에 약간의 부작용이 있을 수 있습니다. 이것이 사용을 피하는 좋은 이유입니다. id 당신이 정말로 필요하지 않는 한 속성.

결국 JavaScript에서 명명된 전역을 사용하지 않는 것이 좋습니다. "취약한" 코드로 이어지는 방법에 대해 이전에 사양을 인용했지만 다음은 요점을 파악하는 데 필요한 전체 텍스트입니다.

일반적으로 이것에 의존하면 코드가 부서지기 쉽습니다. 이 API에 매핑되는 ID는 예를 들어 웹 플랫폼에 새로운 기능이 추가되는 등 시간이 지남에 따라 달라질 수 있습니다. 이 대신 사용 document.getElementById() or document.querySelector().

HTML 사양 자체가 이 기능을 피하도록 권장한다는 사실 자체가 말해주는 것 같습니다.

spot_img

최신 인텔리전스

spot_img

우리와 함께 채팅

안녕하세요! 어떻게 도와 드릴까요?