类数组转数组

什么是类数组ArrayLike?

我们举一个比较经典的类数组(最经典的类数组是Arguments,这里暂且不说)。

1
var nodeList=document.querySelectorAll("div");

这个nodeList就是一个类数组。何以见得?它可以用nodeList[0]取到第一个子元素。但是当我们用console.log(nodeList instanceof Array)返回false也就是说它并不是数组的实例,也就不是数组。

ArrayLike对象的精妙在于它和javascript原生的Array类似,但是它是自由构建的,它来自开发者对javascript对象的扩展,也就是说:对于它的原型(prototype)我们可以自由定义,而不会污染到javascript原生的Array。

类数组转换为数组之后进行操作有什么优势?

简而言之:便捷。Array在js里面是非常强大有用的,它有很多方法:shift,unshift,splice,slice,concat,reverse,sort。ECMAscript 2015又新增了一些方法forEach,isArray,indexOf,lastIndexOf,every,some,map,filter,reduce等等。包括那个IT笑话,“对程序员来说push的反义词是pop(^_^)” 说的都是和数组相关的。但是这些强大的方法,类数组是不一定全部支持的。当我们需要进行数组属性操作的时候才发现,啊原来这是个类数组,啊,要是能变成数组多好啊,否则我还得自己写。虽然每一种方法都是可以自己靠基础api实现的,但是每次都做重复的基础工作,多枯燥。学会偷懒有时候能帮助提高效率~~

#转换方式:Array.prototype.slice.call(arrayLike)

首先Array.prototype.slice.call(arrayLike)的结果是将arrayLike对象转换成一个Array对象。所以其后面可以直接调用数组具有的方法。譬如

1
Array.prototype.slice.call(arrayLike).forEach(function(element,index){ //可以随意操作每一个element了 })

解析点1:Array.prototype.slice表示数组的原型中的slice方法。注意这个slice方法返回的是一个Array类型的对象(这句话很多分析的文章没有点破,我就问了凭什么非得是slice啊?原因就在这)。splice行不行呢?Array.prototype.splice.call(arrayLike,0)这种形式也可以。只要返回的是原数组就可以。当然,那种写法更省事一目了然。

解析点2:能调用call的只有方法,所以不能用[].call这种形式,得用[].slice。而call的第一个参数表示真正调用slice的环境变为了arrayLike对象。所以就好像arrayLike也具有了数组的方法。


本文结束,感谢阅读。

本文作者:melody0z
本文链接:https://melodyvoid/JavaScript/clas-aray-to-aray.html
欢迎转载,转载请注明文本链接

坚持原创技术分享,您的支持将鼓励我继续创作!