Javascript伪数组解析
简介
js没有真正的数组,因此typeof不能识别数组与对象。用constructor检测在不同帧和窗口创建的数组会给出false,所以应当使用Array.prototype.toString.call(arr) === "[object Array]"。常见的伪数组有arguments,通过调用getElementsByTagName、document.childNodes等方法得到的NodeList对象。
实现一个伪数组
var pseudoArr = {0:'a', 1:'b', length: 2};
var arr = Array.prototype.slice.call( pseudoArr );
console.log( arr );//["a","b"]
//下标没有对应的值
var pseudoArr1 = {a:'a', b:'b', length: 2};
var arr1 = Array.prototype.slice.call( pseudoArr1 );
console.log( arr1 );//[undefined x 2];
console.log( arr1[0] );//undefined
//length不是数值
var pseudoArr2 = {0:'a', 1:'b', length: 'num'};
var arr2 = Array.prototype.slice.call( pseudoArr2 );
console.log( arr2 );//[];
console.log( arr2[0] );//undefined
slice内部原理
pseudoArr1、pseudoArr2均转化为了数组,但是数组中的值为undefined,查看V8引擎的array.js源码
function ArraySlice(start, end) {
CHECK_OBJECT_COERCIBLE(this, "Array.prototype.slice");
var array = TO_OBJECT_INLINE(this);
var len = TO_UINT32(array.length);
var start_i = TO_INTEGER(start);
var end_i = len;
if (!IS_UNDEFINED(end)) end_i = TO_INTEGER(end);
if (start_i < 0) {
start_i += len;
if (start_i < 0) start_i = 0;
} else {
if (start_i > len) start_i = len;
}
if (end_i < 0) {
end_i += len;
if (end_i < 0) end_i = 0;
} else {
if (end_i > len) end_i = len;
}
var result = [];
if (end_i < start_i) return result;
if (UseSparseVariant(array, len, IS_ARRAY(array), end_i - start_i)) {
%NormalizeElements(array);
%NormalizeElements(result);
SparseSlice(array, start_i, end_i - start_i, len, result);
} else {
SimpleSlice(array, start_i, end_i - start_i, len, result);
}
result.length = end_i - start_i;
return result;
}
var array = TO_OBJECT_INLINE(this);
var len = TO_UINT32(array.length);
这段代码可以看出slice不需要this为array类型,只需要有length属性即可。并且当length不为数字时,TO_UINT32(array.length)返回0。 由此得出结论:pseudoArr1转化为length为2的数组,其值初始化为undefined;pseudoArr2转化为length为0的数组,其值自然为undefined。
PS:chrome、FF下使用console.log打印jQuery中$(),结果为[]。此处的原因在于如果一个对象内部属性存在length和splice方法,那么就会打印出[]。这可能是由于鸭式辨型的缘故,如果一个对象存在length及splice方法,那么就认为它是一个数组。(此处待考证)
var a = {length: 0, splice: function(){}}; a;//[]
star
:100: :+1:
好文章
赞