【分享】有关JS中数据类型判断的兼容性问题之:typeof

WebAdvocate 2010-08-23 04:29:44
加精
JavaScript语言中的对象
众所周知,对象是一种复合数据类型,是一个无序的属性集合,每个属性都有自己的名字和值。它可以有new来创建,但new运算符之后必须有用于初始化对象的构造函数(constructor),还可以使用大括号包含一系列的属性名加上冒号加上属性值构成。

ECMAScript 辨认两种类型的对象:本地对象(native Object)和宿主对象(host Object),以及一个本地对象的子分类-内置对象(ECMA 262 3rd Ed Section 4.3)。本地对象属于JS语言,宿主对象由环境提供,例如,document对象和DOM节点。

其中,JavaScript的本地对象里有共六中基本数据类型,其中有五种原始类型(primitive type):Number, String, Boolean, Null, Undefined. 其它的都是复合数据类型Object。

古老的typeof
ECMAScript中,typeof是一元表达式之一,跟+,-,++,--,void,delete等并列。

typeof的步骤是:
1. 计算一元表达式的值;
2. 如果步骤一结果的类型不是引用类型,跳到步骤4
3. 如果步骤一结果的组成对象是null,返回“undefined”
4. 调用getValue方法
5. 根据下表返回(ECMAScript 262 V3,浏览器类型为):


最新的V5中,对后两项做了调整:


typeof的兼容性问题
<script type="text/javascript">
window.onload = function() {
document.getElementById("info").innerHTML = "typeof undefined == " + (typeof undefined) + //"undefined"
"<br/>typeof null === " + (typeof null) + //"object"
"<br/>typeof true === " + (typeof true) + //"boolean"
"<br/>typeof 1 === " + (typeof 1) + //"number"
"<br/> typeof \"hello\" === " + (typeof "hello") + //"string"
"<br/> typeof new Date() === " + (typeof new Date()) + //"object"
"<br/> typeof (new Date()).getDate === " + (typeof (new Date()).getDate) + //"function"
"<br/> typeof document.getElementById === " + (typeof document.getElementById) + //"function"
"<br/> typeof document === " + (typeof document); //"object"
}
</script>
<div id="info"></div>
以上测试用例,测试的是各种数据类型的typeof表达式结果。
只有IE中,对document.getElementById方法返回“object”。

可见,typeof只适合检测基本的数据类型,对于复合型的数据类型都是返回“object”,如以上的Date对象。再比如:
function A(){
}
var a=new A();
alert(type of a);//object


如何判断一个JS对象的类型是否是function?
<script type="text/javascript">
function isFunction( fn ) {
return !!fn && //不为空,存在
!fn.nodeName && //不是节点对象
fn.constructor != String && //不是字符串类型
fn.constructor != RegExp && //不是正则表达式
fn.constructor != Array && //不是数组
/function/i.test( fn + "" ); //toString()中包含"function"
}
alert(isFunction(document.getElementById)); //true
</script>
以上是大师John Resig判断是否Function的方法。很经典。利用的是排除法,聪明……佩服……

备注
【1】. GetValue (V):

1. 如果V不是引用类型,返回V;
2. 调用getBase(V)方法,返回V的基本对象类型;
3. 如果步骤二返回null,抛出ReferenceError异常;
4. 调用步骤二返回值的[[Get]]方法,通过GetPropertyName(V)求原型名称;
5. 返回第四步的值。

* GetBase(V). Returns the base object component of the reference V.
* GetPropertyName(V). Returns the property name component of the reference V.



更多浏览器兼容性问题,跨浏览器开发专版:【分享】浏览器兼容性问题目录
...全文
3005 56 打赏 收藏 转发到动态 举报
写回复
用AI写文章
56 条回复
切换为时间正序
请发表友善的回复…
发表回复
hclscut 2011-11-20
  • 打赏
  • 举报
回复
很好,楼主很给力呀!
熊哥club 2010-08-27
  • 打赏
  • 举报
回复
学习了
WebAdvocate 2010-08-26
  • 打赏
  • 举报
回复
[Quote=引用 42 楼 rainsilence 的回复:]

HTML code
<script>

function isFunction(handler) {
return Object.prototype.toString.call(handler) === "[object Function]";
}
function test() {}
var arr = "123";
alert(isFunction(test));
aler……
[/Quote]

恩 不错 这个更好,更简洁直接。这是用了Object对象未被修改的 toString()方法。
wang1984hua 2010-08-26
  • 打赏
  • 举报
回复
每天回帖即可获得10分可用分!
xxmiaoyong126com 2010-08-26
  • 打赏
  • 举报
回复
JS看起来很有艺术感,
虽然已不做开发,
  • 打赏
  • 举报
回复
简直是及时雨啊,学习了,谢谢楼主
superbulldeng 2010-08-26
  • 打赏
  • 举报
回复
学习学习,太厉害了
ball1222 2010-08-26
  • 打赏
  • 举报
回复
谢谢分享
zjmotion 2010-08-26
  • 打赏
  • 举报
回复
function test(){}

function isFunction(obj)
{
return typeof(obj) == 'function';
}

alert(isFunction(test));


不行???
凤凰涅檠 2010-08-26
  • 打赏
  • 举报
回复
mark up
rainsilence 2010-08-25
  • 打赏
  • 举报
回复
Jquery的源代码更简单把。。
rainsilence 2010-08-25
  • 打赏
  • 举报
回复
<script>

function isFunction(handler) {
return Object.prototype.toString.call(handler) === "[object Function]";
}
function test() {}
var arr = "123";
alert(isFunction(test));
alert(isFunction(document.getElementById));
alert(isFunction(arr));
</script>
fym66666 2010-08-25
  • 打赏
  • 举报
回复
学习了
迷茫的主宰 2010-08-25
  • 打赏
  • 举报
回复
good 非常好
sundown2000 2010-08-25
  • 打赏
  • 举报
回复
很受用,谢谢
dingnaijing 2010-08-25
  • 打赏
  • 举报
回复
.........
wymming1126 2010-08-25
  • 打赏
  • 举报
回复
厉害 学习学习
shenbingyi 2010-08-24
  • 打赏
  • 举报
回复
好好学习一下
马老虎 2010-08-24
  • 打赏
  • 举报
回复
WebAdvocate 2010-08-24
  • 打赏
  • 举报
回复
[Quote=引用 18 楼 falizixun2 的回复:]

众所周知,对象是一种复合数据类型,是一个无序的属性集合,每个属性都有自己的名字和值。它可以有new来创建,但new运算符之后必须有用于初始化对象的构造函数(constructor),还可以使用大括号包含一系列的属性名加上冒号加上属性值构成。

这点有点不太理解,使用大括号包含一系列的属性名加上冒号加上属性值的结构好象不能用new关键来创建实例吧!
[/Quote]你的断句有点儿问题,呵呵,应该是这样:
众所周知,对象是一种复合数据类型,是一个无序的属性集合,每个属性都有自己的名字和值。它可以有new来创建,但new运算符之后必须有用于初始化对象的构造函数(constructor);还可以使用大括号包含一系列的属性名加上冒号加上属性值构成。
加载更多回复(28)

5,006

社区成员

发帖
与我相关
我的任务
社区描述
解读Web 标准、分析和讨论实际问题、推动网络标准化发展和跨浏览器开发进程,解决各种兼容性问题。
社区管理员
  • 跨浏览器开发社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧