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
|