[譯]DOM:元素ID就是全局變量


原文:http://www.2ality.com/2012/08/ids-are-global.html


有人在twitter上提到了:在Chrome的JavaScript終端中,你只需要輸入一個元素的ID,就可以訪問到這個元素.@johnjbarton給了解釋,這是因為所有的元素ID都是全局變量.本文再詳細解釋一下.

標准規范

HTML5規范文檔中指出:如果一個元素符合下面兩條規則中的任一條,則window對象中必須要有與之對應的一個屬性,屬性值就是這個對象.

  • 如果一個元素擁有ID屬性,那么ID屬性的屬性值就會成為window對象的屬性名.
  • 如果一個元素擁有name屬性,那么name屬性的屬性值就會成為window對象的屬性名.但這個元素的標簽名必須是: a, applet, area, embed, form, frame, frameset, iframe, img, object,其中的一個.

讓我們看一個例子.假定存在一個頁面,該頁面包含了一個ID屬性為“foo”的div元素:

<div id="foo"></div>

這樣一來,上面的的div元素就可以通過window.foo(和其他的window屬性一樣),或者全局變量foo來訪問到.比如,在Chrome控制台中,你可以這樣做:

> "foo" in window
true
> foo
<div id="foo"></div>

Firefox

火狐(14)的工作方式略有不同.

> "foo" in window
false
> typeof foo  // 這個全局變量到底有木有?
object

//錯誤控制台輸出了下面的警告
.
//Element referenced by ID/NAME in the global scope. //Use W3C standard document.getElementById() instead. > foo [object HTMLDivElement]
//錯誤控制台輸出了下面的警告.
//Element referenced by ID/NAME in the global scope. //Use W3C standard document.getElementById() instead.
> "foo" in window 
true

這到底是怎么一回事?初始化時,window並沒有屬性foo.但在第一次訪問這個屬性的時候(通過window.foo屬性直接訪問或者通過全局變量foo來訪問都可以),它會被自動建立.

譯者注:我在Firefox14,15,18中都沒有發現警告,不過在Firefox12試驗時,的確有警告.

[注意:例子中的代碼只能在網頁中通過script標簽運行才能見效,不能通過終端運行.這是因為終端在處理全局對象時,使用了不同的方式.]

譯者注:我在Firebug中嘗試例子中的代碼,並沒發現有什么差別.

一旦你嘗試讀取foo的值,雖然會正常返回那個div元素,但同時錯誤控制台會有警告,告訴你不應該那么做.很顯然,這樣的警告是正確的:在終端調試的時候,你可以使用這個特性,但在實際的代碼中,不應該使用.

Cody Lindley寫了一個jsPerf測試來比較通過全局變量訪問foo和通過window.foo來訪問foo的性能差別.有趣的是,只有在Firefox中訪問window.foo更快點.


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM