除了上述对象外,我们还可以自己构造 arraylike,对任意对象下标赋值,它就是一个 arraylike 了,但这样做还不够,如果用 array 原型方法操作它,会被默认为是一个空数组:
var a ={ slice:[].slice, push:[].push }; a[0]="hello"; a[1]="world"; console.log( a.slice().length );// 期望得到 2,但结果为 0
a.push("apple"); console.log( a.length );// 期望得到 3,但结果为 1
console.log( a[0], a[1]);// 我们看到这里的 a[0] 已经被Apple覆盖
解决这个问题的办法是给它加上 length 属性,对指定的范围起到保护作用,注意以下加粗部分:
var a ={ push:[].push,length:2}; a[0]="hello"; a[1]="world"; console.log( a.length );// 2 a.push("apple"); console.log( a.length );// 3 console.log( a[0], a[1], a[2]);// hello, world, apple
经常用 jQuery 的同学可能已经发现,console.log($(selector)) 会出来一个“数组”,里面有一堆 dom 节点,其实 $() 得到的结果也是一个 arraylike,在控制台下以数组的形式显示不过是 jQuery 的一个小把戏而己,控制台会对结果做鸭子类型检测,如果检测结果是一个数组,控制台将会对它以数组的方式来显示。那么检测的依据是什么呢?经过排除法得出,是 length 属性和 splice 属性,对比以下两个 console.log 在控制台下的显示:
var a ={ length:2}, b ={ length:2, splice:[].splice }; a[0]= b[0]="hello"; a[1]= b[1]="world"; console.log( a ); console.log( b );
如果某个动物长得像鸭子,它的叫声也像鸭子,那么我们认为它就是鸭子。这种判断方法称之为鸭子类型检测(duck typing),当然,这种方法判断的结果不一定准确,但在某些场景下已经够用了。在 javascript 中,针对数组做 typeof 操作,得到的结果是 “object”,为了正确判断数组,很多库也都采用了鸭子类型检测,控制台就是采用鸭子类型检测来判断数组,它的判断条件是:当对象的 length 属性是一个数字,并且 splice 属性是一个 function,那么该对象就是数组,所以我们会看到上面的对象 b,在控制台下以数组的方式显示出来。
原文:http://www.cnblogs.com/abapscript/p/4861963.html