各浏览器对typeof运算符的实现差异

1,IE6/7/8中typeof运算符对BOM对象如window,document,location,history等对象的方法返回“object”,标准浏览器都返回“function”。

1
2
3
4
5
6
alert(typeof window.alert); // object
alert(typeof document.write); // object
alert(typeof document.getElementById); // object
alert(typeof document.getElementsByTagName); // object
alert(typeof location.reload); // object
alert(typeof history.go); // object

 

2,Safari/Chrome对正则对象返回function,其它浏览器返回object

1
2
3
var bb = new RegExp('bb');
alert(typeof /aa/);// --> function
alert(typeof bb);// --> function

 

3,Safari对NodeList返回function,其它浏览器返回object

1
2
3
4
var nodes1 = document.body.children
    nodes2 = document.body.childNodes;
alert(typeof nodes1);
alert(typeof nodes2);

 

关于typeof运算符,ECMAScript5 11.4.3节有相关说明(注意result都是字符串)

从上表可以看出

1,基本类型

对于Undefined、Null、Boolean、Number、String返回字符串"undefined"、"object"、"boolean"、"number"、"string"。 需注意的是对于Null返回的不是"null"而是"object",据说是ECMAScript早期版本的笔误而一直延续至今。

2,对象类型

对象类型又分本地对象(Object)和宿主对象(window),本地对象又分普通对象和函数类型对象。因为JS中函数是一等公民,即函数本身也是个对象。因此需要区分下。这里的对象指没有实现call方法的对象。

普通对象如Object,Array等返回 “object”。

函数类型对象如new Function方式或function fn(){}、var fn = function(){}方式返回“function”。

宿主对象如window,没有实现call方法的对象返回是宿主自定义的,但不能是"undefined"、"boolean"、"number"、"string"。即宿主的实现不能是JS的基本类型的返回值,这是语言最核心的地方,否则会让人很困惑。

 

以上就是ECMAScript对typeof描述的全部。

对于以上列举的三个差异的第二条:Safari/Chrome对正则对象返回function,其它浏览器返回object,这可以认为是Safari/Chrome的Bug,即没有按标准ECMAScript5实现。正则表达式是非宿主普通对象(见ECMAScript5 15.10 RegExp (Regular Expression) Objects),而又没有实现call方法。如

1
2
3
var reg = /aa/;
alert(reg.call); // undefined
alert(reg.test); // native code

因此对于typeof运算应该返回“object”而不是“function”。

 

对于第一条和第三条,宿主对象,除了不能返回"undefined"、"boolean"、"number"、"string"外,具体返回啥由浏览器自行实现。我们看一个示例window.alert

1
alert(alert.call); // IE6/7/8中undefined,IE9/Firefox/Safari/Chrome/Opera中native code

可以看到IE6/7/8中alert是没有call方法的,因此typeof window.alert,IE6/7/8中返回“object”也没有违背规范,只是让开发者觉得很困惑,因为从学JS的第一天开始就认为alert是window对象的一个方法/函数。

正因为ECMAScript对于宿主对象没有严格的定义typeof,从而在IE中使用typeof运算符返回"date"、"unknow"之类的就不足为奇了。

1
2
xhr = new ActiveXObject("Msxml2.XMLHTTP");
alert(typeof xhr.abort); // IE6/7/8/9中都返回 unknow
posted @ 2016-05-19 15:03  黑客PK  阅读(720)  评论(0编辑  收藏  举报