什么是 arraylike?
在网页前端,我们经常会遇到一些具有部分数组特性的对象,如 arguments、nodelist 等,这些对象是一组数据的有序集合,有长度、下标等特性,它们不是真正意义的 array,像这样的对象,我们喜欢称它们为 arraylike 或伪数组,我们不能通过 array 的原生方法来直接操作它们,但利用 javascript 弱类型特性,我们可以跨原型链来对它们进行操作,如:Array.prototype.slice.call(arguments, 0)。
构造 arraylike
除了上述对象外,我们还可以自己构造 arraylike,对任意对象下标赋值,它就是一个 arraylike 了,但这样做还不够,如果用 array 原型方法操作它,会被默认为是一个空数组:
1 2 3 4 5 6 7 |
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] 已经被覆盖 |
解决这个问题的办法是给它加上 length 属性,对指定的范围起到保护作用,注意以下加粗部分:
1 2 3 4 5 6 7 |
var a = { push: [].push, <strong>length: 2</strong> }; 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 |
console 对于 arraylike 的显示优化
经常用 jQuery 的同学可能已经发现,console.log($(selector)) 会出来一个“数组”,里面有一堆 dom 节点,其实 $() 得到的结果也是一个 arraylike,在控制台下以数组的形式显示不过是 jQuery 的一个小把戏而己,控制台会对结果做鸭子类型检测,如果检测结果是一个数组,控制台将会对它以数组的方式来显示。那么检测的依据是什么呢?经过排除法得出,是 length 属性和 splice 属性,对比以下两个 console.log 在控制台下的显示:
1 2 3 4 5 |
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)
如果某个动物长得像鸭子,它的叫声也像鸭子,那么我们认为它就是鸭子。这种判断方法称之为鸭子类型检测(duck typing),当然,这种方法判断的结果不一定准确,但在某些场景下已经够用了。在 javascript 中,针对数组做 typeof 操作,得到的结果是 “object”,为了正确判断数组,很多库也都采用了鸭子类型检测,控制台就是采用鸭子类型检测来判断数组,它的判断条件是:当对象的 length 属性是一个数字,并且 splice 属性是一个 function,那么该对象就是数组,所以我们会看到上面的对象 b,在控制台下以数组的方式显示出来。
转载请注明:飞飞的个人网站 » 关于javascript的arraylike