Javascript类型检测
来源:互联网 发布:mac五国循环重启 编辑:程序博客网 时间:2024/05/22 03:25
开门见山,我们先来看一下代码:
var
is =
function
(obj,type) {
var
toString = Object.prototype.toString;
var
_baseTypes = {
'undefined'
:
'undefined'
,
'number'
:
'number'
,
'boolean'
:
'boolean'
,
'string'
:
'string'
};
return
(_baseTypes[
typeof
obj]===type)||
(type ===
"Null"
&& obj ===
null
) ||
(type===
'Function'
&&
"object"
===
typeof
document.getElementById ?
/^\s*\bfunction\b/.test(
""
+ obj):toString.call(obj).slice(8,-1) === type)||
obj
instanceof
type;
};
在讲解这个函数之前,让我们先来看一下javascript类型判断的几个关键:
typeof
typeof运算符,用于判断一个或值是哪种类型的。
由于Javascript语言的灵性性与执行环境的复杂性,typeof运算符并不能正确判断出所有的类型。但对于基本数据类型,typeof具有神奇的功效,正如在 is 函数中看到的那样,_baseTypes变量中定义了typeof可以正确识别的基本数据类型列表,其中键为类型名称,值为typeof运算结果。
instanceof
instanceof可以检测某个对象是不是另一个对象的实例。
new String('abc') instanceof String //true
instanceof还可以检测父类型。
function
Animal() {};
function
Pig() {};
Pig.prototype =
new
Animal();
alert(
new
Pig()
instanceof
Animal);
// true
可以看出,instanceof不适合用来检测一个对象本身的类型。
Constructor
所有对象都拥有一个constructor属性,它指向该对象的构造函数。
对于复合数据类型,我们可以采用如下方式进行检测:
isArray:
function
(arr) {
return
!!arr && arr.constructor == Array;
}
但是比较悲剧的是这种行为并不是确定的,在一些极其特殊的情况下,会产生意外的结果:
<div
class
=
"cnblogs_Highlighter"
><pre
class
=
"brush:javascript"
>
var
iframe = document.createElement(
'iframe'
);
document.body.appendChild(iframe);
var
xArray = window.frames[window.frames.length-1].Array;
var
arr =
new
xArray(1, 2, 3);
// [1,2,3]
alert(arr
instanceof
Array);
//false
</pre>
</div>
下面是Johg Resig 《pro javacript Techniques》书中的一张列表:
Duck Typing
在犀牛书里,提到一句老话:"如果走路像鸭子,叫声像鸭子,那他就是鸭子"。换而言之,对于Array来说,如果一个对象有splice和join属性,那它就是一个Array:
function
isArray(o) {
return
o !=
null
&&
typeof
o === ‘object’ &&
'splice'
in
o &&
'join'
in
o;
}
显然,鸭子检测很容易误把自造的天鹅也当成鸭子:
alert(isArray({
'splice'
:
''
,
'join'
:
''
}));
// true
注:buck typing并不关注于类型,它关注的是行为,它是实际作用是相互之间约定一种行为接口,好实现类似于多态的调用
Object.toString
ECMA-262中的解释:
Object.prototype.toString()
when the toString method is called,the following steps are taken:
1.get the [[Class]] property of this object //得到内部属性[[Class]]
2.conpute a string value by concatenating the three strings "[object",Result(1),and"]" //构造一个字符串类型似于[object xxx]
3.return results(2) //返回第2条的执行结果
注:[[Class]]为对象的内部属性,无法真接访问到
这样,就有了:
function
isArray(o) {
return
Object.prototype.toString.call(o) ===
'[object Array]'
;
}
因为是字符串比较,也就解决了环境问题和语法灵活性所带来的变化,因此比较稳定。
好,讲到现在,想必大家对javascript类型判断应该有一个较为深入的理解,我想通过自已的能力,应该也可以写一个比较完善的类型判断函数,那下面就来看一下我是如何实现的。
var
is =
function
(obj,type) {
var
toString = Object.prototype.toString;
var
_baseTypes = {
'undefined'
:
'undefined'
,
'number'
:
'number'
,
'boolean'
:
'boolean'
,
'string'
:
'string'
};
return
(_baseTypes[
typeof
obj]===type)||
(type ===
"Null"
&& obj ===
null
) ||
(type===
'Function'
&&
"object"
===
typeof
document.getElementById ?
/^\s*\bfunction\b/.test(
""
+ obj):toString.call(obj).slice(8,-1) === type)||
obj
instanceof
type;
};
因为考虑到实用性,这里是通过传入对象obj和期望类型type,返回boolean值,true为obj为type类型,false为obj不为type类型来实现的.
首先,var toString = Object.prototype.toString;这里保存了一份对Object的原生toString方法的引用,方便后面使用
var _baseTypes = {'undefined':'undefined','number':'number','boolean':'boolean','string':'string'};
这里保存了一份对于typeof可以检测出来的基本数据类型的对象列表,其键类型名称,值为typeof该类型的结果。
然后:进行类型的检测,返回结果。
(_baseTypes[typeof obj] === type) :检测是否为基本数据类型
(type === 'Null' && obj === null):
因为null实际上属于Object类型,因此typeof null 和Object.prototype.toString(null)返回的结果都为object和[Object object]
在实际需求中,我们通常希望将null单独列出来作为一种类型来进行判断
(type==='function'&&'object'===typeof document.getElementById?/^\s*\bfunction\b/.test(""+obj):toString.call(obj).slice(8,-1)===type)
这里实际上是在判断obj是否是一个函数,而IE6存在bug,无法正确识别getElementById这类函数,因此做了上些特殊的处理。
obj instanceof type:判断obj是否为type的实例
这里主要是来处理一引起特殊情况,如一些自定义对象的问题。
function
Animal() {}
function
SubArray() {}
SubArray.prototype = [];
var
toString = Object.prototype.toString;
alert(toString(
new
Animal()));
alert(toString(
new
SubArray()));
// firefox: [object Window]
// ie: [object Object]
// chrome: [object global]
alert(
new
SubArray()
instanceof
Array);
// true
alert(
new
Animal()
instanceof
Animal);
// true
好,并不多了,最后我们来看一个测试结果:
兼容判断类型列表:
基本数据类型 undefined,string,number,boolean
复合数据类型 Date,String,Boolean,Number,Object,Function,Array,RegExp,Error
其他 instanceof 的范畴
参考:
- javascript 浏览器类型检测
- Javascript类型检测
- JavaScript类型的检测
- javascript 类型检测
- JavaScript中类型检测
- javascript 类型检测
- JavaScript类型检测
- JavaScript 的类型检测
- JavaScript-数据类型-类型检测
- JavaScript检测浏览器类型
- JavaScript类型检测详解
- JavaScript 类型检测
- javascript-深入浅出-类型检测
- javascript的类型检测
- JavaScript变量类型检测
- javascript类型检测
- JavaScript检测类型
- JavaScript的类型检测
- codeforces 429A Xor-tree
- java.lang.IllegalArgumentException: id to load is required for loading
- 建站学习笔记(一)开篇+WWW
- 递归将树转化成json字符串
- 理解Javascript_01_理解内存分配
- Javascript类型检测
- 计算日期
- [LeetCode] Interleaving String
- Plus One
- AndroidManifest.xml - activity 详细说明
- Uva 12296 - Pieces and Discs 切割多边形 ,判断多边形和圆相交
- android:Invalid start tag RelativeLayout
- Path Sum
- 归并排序的递归版本