数据类型检测
//定义
//定义
var classtype = {},
toString = classtype.toString;
"Boolean Number String Function Array Date RegExp Object Error".split(" ").forEach(function(name,idx) {
classtype['[object ' + name + ']'] = name.toLowerCase();
});
classtype的形式如下
classtype = {
"[object Boolean]": "boolean",
"[object Number]": "number"
...
};
function type(obj) {
return obj != null ? String(obj) : classtype[toString.call(obj)] || 'obj';
}
type 函数返回的是数据类型
但有一点想不明白,为什么要这么麻烦,可以利用下面方法也可以得到数据类型而且更方便省事
function type2(obj) {
return Object.prototype.toString.call(obj).slice(8,-1).toLowerCase();
}
isFunction & isObject;
function isFunction(value) {
return type(value) === 'function';
}
function isObject(obj) {
return type(obj) === 'object';
}
直接调用type函数,判断返回的类型字符串,即可得到数据类型了
isWindow
function isWindow(obj) {
return obj != null && obj.window == window;
}
判断是否为浏览器对象
要为window对象首先满足的条件是不能为null 或者 undefined,并且obj.window为自身的引用
isDocument
function isDocument(obj) {
return obj != null && obj.nodeType == obj.DOCUMENT.NODE;
}
判断是否为document对象
节点上面有 nodeType 属性,每个属性值都有对应的常量,document的nodeType 值 为9,常量为DOCUMENT_NODE
isPlainObject
function isPlainObject(obj) {
return isObject(obj) && !isWindow(obj) && Object.getPrototypeOf(obj) == Object.prototype;
}
判断是否为纯粹对象
首先必须是对象 isObject(obj),并且不是window 对象 !isWindow(obj)
最后必须obj的原型要和Object的原型相等
isArray
isArray = Array.isArray ||
function(object) { return object instanceof Array}
这个方法用来判断是否为数组对象
如果浏览器支持Array.isArray 就采用原生方法,否则就是用检测数据是否为Array的实例,
不知道为何作者这里这么写,也可以利用上面 判断数据类型的 type2方法
likeArray
function likeArray(obj) {
var length = !!obj && // obj必须存在
'length' in obj && // obj 中必须存在 length 属性
obj.length, // 返回 length的值
type = $.type(obj) // 调用 type 函数,返回 obj 的数据类型。这里我有点不太明白,为什么要覆盖掉上面定义的 type 函数呢?再定义多一个变量,直接调用 type 函数不好吗?
return 'function' != type && // 不为function类型
!isWindow(obj) && // 并且不为window类型
(
'array' == type || length === 0 || // 如果为 array 类型或者length 的值为 0,返回true
(typeof length == 'number' && length > 0 && (length - 1) in obj) // 或者 length 为数字,并且 length的值大于零,并且 length - 1 为 obj 的 key
)
}
判断是否为数据是否为类数组。
类数组的形式如下:
likeArrayData = {
'0': 0,
'1': 1,
"2": 2,
length: 3
}
不过上面如果是Array 也会返回true,感觉不是很严谨,我们再来看看《JavaScript权威指南》中给出的判断方法,
但根据定义函数也有length(形参的个数)属性,也应该是类数组对象,但是如果o是一个函数, typeof o === 'function' 而非
'object' ,因此isArrayLike 会返回false 感觉是定义的不严谨造成的
function isArrayLike(o) {
if(o && // o不是null、undefined等
typeof o === 'object' && // o是对象
isFinite(o.length) && // o.length是有限数值
o.length >= 0 && // o.length为非负值
o.length === Math.floor(o.length) && // o.length是整数
o.length < 4294967296) // o.length < 2^32
return true
else
return false
}