這是一個遺留的范圍鏈問題,起源于JavaScript1.0到1.3,當(dāng)時編程語言與我們現(xiàn)在所稱的DOMAPI(當(dāng)時的“動態(tài)HTML”)沒有區(qū)別。
如果窗體控件(此處:select
元素)是窗體的一部分(form
元素),則Form
對象,該對象表示form
元素是控件事件處理程序?qū)傩灾捣秶溨械牡谌齻€-下一個(第二個-下一個是表單控件對象本身,其次是該代碼的變量對象)。
JavaScriptJava是由BrendanEich(當(dāng)時在Netscape)設(shè)計的,它是一種編程語言,對于初學(xué)者來說很容易使用,并且可以很好地處理?文檔(作為對Sun的JAVA的補充;因此它是一個永遠令人困惑的名字)。因為在早期語言和(Netscape)DOM API是一種,這種簡化(過度)也適用于DOMAPI:A Form
對象具有包含在其表示為引用相應(yīng)窗體控件對象的屬性名稱的窗體中的控件的名稱。..你可以寫
myForm.border
它是符合標(biāo)準(zhǔn)的專有速記(W3C DOM級別2 HTML),但同樣向后兼容
document.forms["myForm"].elements["border"]
現(xiàn)在,如果在窗體控件的事件處理程序?qū)傩灾抵惺褂么绑w控件的名稱以某種形式,就像
<form …>
<… name="border" onchange='border(this.value)' …></form>
這和你寫的一半專利一樣
<form …>
<… name="border" onchange='this.form.border(this.value)' …></form>
或者是符合標(biāo)準(zhǔn)的
<form …>
<… name="border" onchange='this.form.elements["border"](this.value)' …></form>
因為一個潛在的全球border()
函數(shù)的屬性。ECMAScript最后一個是全局物體,后這個Form
對象(實現(xiàn)HTMLFormElement
接口在W3CDOM中),在作用域鏈中。
但是,此處引用的窗體控件對象由border
不可調(diào)用(不實現(xiàn)ecmaScript-內(nèi)部的[[Call]]
方法或?qū)崿F(xiàn)它,以便在調(diào)用時拋出異常)。因此,如果您試圖用border(this.value)
..TypeError
拋出異常,您應(yīng)該在腳本控制臺中看到這個異常(比如Chromium16.0.912.77[Developer Build 118311 linux]的開發(fā)工具中的“TypeError:邊框不是函數(shù)”)。
20世紀(jì)90年代,Netscape的競爭對手微軟(Microsoft)不得不將該功能復(fù)制到MSHTML DOM因此,為Netscape編寫的代碼也將在InternetExplorer(3.0)中運行,JScript(1.0)。微軟的競爭對手也出于同樣的原因?qū)⑵鋸?fù)制到DOM實現(xiàn)中。它成為了準(zhǔn)標(biāo)準(zhǔn)(現(xiàn)稱“DOM級0").
然后是DOMLevel2HTML規(guī)范,這是當(dāng)時標(biāo)準(zhǔn)化和擴展現(xiàn)有DOM實現(xiàn)的通用特性的持續(xù)努力。自2003-01-09年度起獲W3C推薦,ECMAScript語言綁定指定HTMLCollection
s可以通過它們的名稱訪問。或 ID使用括號屬性訪問器語法。[
…]
,相當(dāng)于調(diào)用namedItem()
方法對象的HTMLCollection
接口。
form
窗體中窗體控件的元素對象和元素對象是HTMLCollection
在W3C DOM中,HTMLDocument::forms
和HTMLFormElement::elements
分別。但是為了在瀏覽器中向后兼容,
document.forms["myForm"].elements["myControl"]
需要等價物到
document.myForm.myControl
因此,最遲在W3CDOMLevel2HTML接口的實現(xiàn)中,這個特性開始應(yīng)用于具有ID的元素 (id
屬性值)(例如,在Chrome中可以看到)。
因此,16年前在JavaScriptDOM中引入的方便特性至今仍像客戶端DOM腳本中的bug一樣咬你一口。
如果避免對窗體控件和窗體使用相同的名稱或ID,將其用作用戶定義函數(shù)的標(biāo)識符,并且已用于內(nèi)置窗體屬性(如action
, submit
,和reset
),這就不再是什么問題了。此外,對函數(shù)及其參數(shù)之一使用相同的標(biāo)識符也是個壞主意,因為這使得函數(shù)對象無法從函數(shù)內(nèi)部訪問(函數(shù)上下文的變量對象位于其作用域鏈的第一位)。