Bom和Dom是外部規定的,他們可以遵守也可以不遵守ECMA的規定。所以他們的內置對象可能是Object的實例,也可能不是。
ECMA只是規定了一份標準,但是各個瀏覽器廠商要不要執行這個標準,是他們的自由,所以對於廠商創造的不遵守標準的瀏覽器版本,出現不是Object的實例的常規對象也是有可能的。
是不是Object的實例,是個很籠統的說法,具體怎麼判斷,我這能想到三個方法。
[document.all,Object.create(null),new Object()].forEach(item=>{
console.log(`
${typeof item}
${item instanceof Object}
${Object.prototype.toString.call(item)}
`)
})
document.all (屬於宿主環境瀏覽器,不受ECMA限制) |
Object.create(null) | new Object() | |
typeof | undefined |
object |
object |
instanceof Object | true | false | true |
Object.prototype.toString.call | [object HTMLAllCollection] | [object Object] | [object Object] |
instanceof
instanceof利用原型鏈來確定類型,所以如果利用iframe傳遞過來的值不屬於同一個全局作用域,有不同的全局類型,也會出錯。這讓我想起了星爺的《九品芝麻官》,拿出了明朝的尚方寶劍來斬本朝的官。
Object.prototype.toString
Object.prototype.toString是可以被重寫的。
> Object.prototype.toString.call({})
< "[object Object]"
> Object.prototype.toString = ()=>'這回傻了吧'
> Object.prototype.toString.call({})
< "這回傻了吧"
typeof
typeof是個很籠統的方法,它的返回值很簡單,對引用數據類型只能返回object和function,再具體就做不到了。
什麼時候返回function,什麼時候返回object呢?高程三 說,任何在內部實現了[[Call]]方法的對象,都應該在應用typeof操作符時返回"function"