[英]Javascript: typeof and instanceof results contradicting?
在對象上執行typeof和instanceof時,我看到了相互矛盾的結果。
我有以下測試頁面:
<html>
<body>
<object id="test" />
<script type="text/javascript">
var foo = document.getElementById("test");
console.log(typeof foo); // returns "function"
console.log(foo instanceof Function); // returns false
console.log(foo instanceof Object); // returns true
</script>
</body>
</html>
“typeof foo”返回“function”但“foo instanceof Function”返回false。
這對我來說沒有意義。 對象如何將類型設為函數但不是函數的實例? 另外,我希望“typeof foo”返回“對象”。
object
和embed
HTML元素是宿主對象。
ECMAScript3 11.4.3沒有定義應為這些返回的typeof
。 對象的返回值表是
- 對象(本機的,不實現[[Call]]):
"object"
- 對象(native和implements [[Call]]):
"function"
- 對象(主機):依賴於實現
但是,返回"function"
與ECMAScript5 11.4.3一致:
- 對象(本機的,不實現[[Call]]):
"object"
- 對象(本機或主機並實現[[Call]]):
"function"
- 對象(主機並沒有實現[[Call]]):實現定義,但可能不是
"undefined"
,"boolean"
,"number"
或"string"
。
object
和embed
HTML元素是具有內部[[Call]]屬性的對象,因此typeof
必須返回"function"
。
錯誤268945中對此進行了解釋:
評論#15 ,作者:Boris Zbarsky:
[[Call]]在DOM端是非常有意的:這些是可調用的對象。
評論#16 ,湯姆舒斯特:
這個bug無效,這些對象有[[Call]]內部方法,ES5 11.4.3明確說“Object(native或_host_並且實現[[Call]])”=>“function”。
由於object
和embed
HTML元素實現了內部[[Call]]屬性,因此它們是可調用對象 。 但是,它們不是功能:
4.3.24功能
Object類型的成員,它是標准內置
Function
構造Function
一個實例,可以作為子例程調用
object
HTML元素繼承自HTMLObjectElement.prototype
,並embed
來自HTMLEmbedElement.prototype
HTML元素。
原型鏈繼續
HTMLObjectElement.prototype
HTMLElement.prototype
Element.prototype
Node.prototype
Object.prototype
因此,它們不是Function
實例,因為它們不從Function.prototype
繼承。
基本的事實是DOM元素(例如,使用document.getElementById()
)不是本機JavaScript對象。 相反,它們是主機對象 。 因此,它們不受適用於本機JavaScript對象的通常規則的約束,並且它們的行為將(非常合理地)從一個瀏覽器到下一個瀏覽器變化很大。
簡而言之,所有的賭注都沒有了。 不要依賴於其記錄的API之外的宿主對象的行為。
相關參考:
Safari為typeof document.getElementsByTagName('p')返回' function ',
這讓我很久以前的一段時間,當我假設所有客戶都會返回“對象”時。
測試我們的前概念是很好的,即使異常沒有發生。
此外,調試器很可愛,但它們並不總是報告與瀏覽器相同的值。
在第一個示例中,運行腳本時不存在此dom元素。 在你的第二個,它的答案是正確的,第二個是typeof和constructor之間的區別。 typeof返回一個函數,因為document.getElementById返回一個函數。 構造函數告訴您該函數“HTMLElement”的名稱。
例如,您可以使用var myElement = new HTMLElement()開始創建自己的元素
我不確定為什么為<object>
節點返回'function',但是instaceof Function
失敗的原因是因為它本質上是對構造函數的檢查,其區別可以如此說明
<html>
<body>
<object id="test" />
<script type="text/javascript">
var foo = document.getElementById("test");
var bar = function() {}
console.log( typeof foo );
console.log( foo instanceof Function );
console.log( foo.constructor ); // Object()
console.log( typeof bar );
console.log( bar instanceof Function );
console.log( bar.constructor ); // Function()
</script>
</body>
</html>
所以在這種情況下,它實際上typeof
是奇怪的行為,而不是在一個方式是記錄 ,我可以看到。
我發現了一些額外的奇怪行為。
如果您將javascript代碼移動到對象上方,則typeof正常工作但instanceof不起作用。
<html>
<body>
<script type="text/javascript">
var foo = document.getElementById("test");
console.log(typeof foo); // returns object (this is correct now)
console.log(foo instanceof Function); // returns false (this is correct)
console.log(foo instanceof Object); // returns false (this is wrong)
console.log(foo instanceof HTMLElement); // returns false (this is wrong)
console.log(foo instanceof Node); // returns false (this is wrong)
</script>
<object id="test" />
</body>
VS
<html>
<body>
<object id="test" />
<script type="text/javascript">
var foo = document.getElementById("test");
console.log(typeof foo); // returns function (this is wrong)
console.log(foo instanceof Function); // returns false
console.log(foo instanceof Object); // returns true (this is correct)
console.log(foo instanceof HTMLElement); // returns true (this is correct)
console.log(foo instanceof Node); // returns true (this is correct)
</script>
</body>
所以基本上如果腳本在對象下面,typeof表現得很奇怪,但是如果腳本在對象instanceof之上,則表現得很奇怪。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.