簡體   English   中英

Javascript:typeof和instanceof結果是否矛盾?

[英]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”返回“對象”。

objectembed 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"

objectembed HTML元素是具有內部[[Call]]屬性的對象,因此typeof必須返回"function"

錯誤268945中對此進行了解釋:

  • 評論#15 ,作者:Boris Zbarsky:

    [[Call]]在DOM端是非常有意的:這些是​​可調用的對象。

  • 評論#16 ,湯姆舒斯特:

    這個bug無效,這些對象有[[Call]]內部方法,ES5 11.4.3明確說“Object(native或_host_並且實現[[Call]])”=>“function”。

由於objectembed 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返回一個函數。 構造函數告訴您該函數“HT​​MLElement”的名稱。

例如,您可以使用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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM