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"