定义
在《JavaScript权威指南》中是这样解释类数组对象的:
一种常常完全合理的看法把拥有一个数值length属性和对应非整数属性的对象看做一种类型的数组。
常见的类数组对象有函数中的arguments对象、HTMLCollection、NodeList等。
判断方法
《JavaScript权威指南》中给出的判断方法
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
}
在这里我有一个疑问,根据定义,函数也有length数值属性,应该也是类数组对象。但如果o
是一个函数,那么typeof o
返回的是'function'
,并不是'object'
,以致于调用isArrayLike
函数会得到false
。(感觉还是因为定义不严谨导致的)
underscore中的实现
var isArrayLike = function(collection) {
// 返回参数 collection 的 length 属性值
var length = getLength(collection);
// length是数值,非负,且小于等于MAX_ARRAY_INDEX
// MAX_ARRAY_INDEX = Math.pow(2, 53) - 1
return typeof length == 'number' && length >= 0 && length <= MAX_ARRAY_INDEX;
}
相对来说,underscore中的实现跟定义一样宽松,函数也是类数组对象。甚至传入数组,isArrayLike
函数也会返回true
。
jQuery中的实现
function isArrayLike(obj) {
// 如果obj非null、undefined等,有length属性,则length等于obj.length
// 否则,length为false
var length = !!obj && "length" in obj && obj.length,
// 检测obj的类型
type = jQuery.type(obj)
// 如果obj是function类型 或者是window对象 则返回false
if (type === "function" || jQuery.isWindow(obj)) {
return false
}
// obj本身是数组,则返回true
// obj不是数组,但有length属性且为0,例如{length : 0},则返回true
// obj不是数组,但有length属性且为整数数值,obj[length - 1]存在,则返回true
return type === "array" || length === 0 ||
typeof length === "number" && length > 0 && (length - 1) in obj;
}
结语
类数组对象的判断,不同版本的返回结果有细微的差别。主要原因是因为类数组对象不是规范的,所以不同项目的定义会有所不同。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。