首先上一张花费大量时间整理和排序的表格,里面列出了基本所有数组方法,以及参数、返回值,有需要的朋友可以将图片保存,或者根据自己的需要将图片改造,自行定制。
接下来就按照我的个人思路,依次对该表格里的方法解析之。
Ps,所有的方法都会在2019年12月2日-6日,于chrome 78.0 console控制台进行验证并截图,如果遇到其他人结果不一致的,自行将代码输入到浏览器内验证结果。
Pps,全文较长,共计花费约一个礼拜,建议看官可以先点赞或者收藏慢慢看哦~ ^_^
转换为字符串
JavaScript中将数组转换为字符串,用逗号分隔。
注意1:在转换为字符串时,会同步对数组中的元素做toString,至于结果嘛…看图。
对于结构明确简单的数组可以随意使用,如果习惯用undefined对空值进行标记,或者有对象、数组结构,就要小心了。
注意2:在mdn文档中有提示,“当数组用于字符串环境时,JavaScript 会调用这一方法将数组自动转换成字符串。”这就包含了隐式调用,如果遇到不想用逗号分隔,或者需要显式调用的情况,那就需要下面的join方法啦
用指定字符连接数组元素,参数为空时与toString方法返回值一致。如果想直接连接,传一个空字符串即可
备注:valueOf是JavaScript中的隐式方法,翻译成人话就是你用不着,toLocalString则是转换为本地字符集字符串,由于国内web开发标准、环境使然,该方法和toString返回一致,所以……你也用不着。
操纵、改变数组元素
四种方法分别对应着删除末尾元素,删除首个元素,在开头填装元素,在末尾填装元素,而对应返回值分两种,pop和shift返回元素,unshift和push返回改变后的数组长度。
四种方法在成功执行后都会改变原数组。
注意:Push和unshift方法是可以传入多个参数的,会将参数依次插入数组,但pop和shift无论传什么参数,都只会删除一个元素。如果数组为空,则pop和shift不改变数组,并返回undefined。
concat() 方法用于连接两个或多个数组,该方法不会改变现有的数组,而仅仅会返回被连接数组的一个副本。
备注:和push相比,在参数、返回值、对原数组处理上有不同。由于concat返回新数组,可以通过不传参来实现数组的浅拷贝。
用回调来遍历数组
这些方法有个共同点,即第一个参数都传入一个函数,用来对数组每一项执行回调。相较于传统的for循环,回调写法更加优雅,直观易懂,而且生产环境中json数据很多都是对象数组,采用回调从中取值,筛选等操作都更方便简捷。
注意:因为是在function中,该类方法会导致break、continue失效
forEach() 方法为每个数组元素调用一次函数(回调函数)。该方法不会改变原数组,并且返回undefined。
回调函数接受三个参数:1项目值,2项目索引,3数组本身。
该方法适用于简单粗暴的遍历,可以用于打印,查找等等,在声明其他数组的情况下,也可以将其视为万能方法。
filter() 方法创建一个包含通过测试的数组元素的新数组。
说人话就是筛,符合条件的在回调里return true,不符合的false,把所有true的元素挑出来,filter形成一个新数组。该方法不修改原数组,只会返回一个return true的元素组成的新数组。
回调函数接受三个参数:1项目值,2项目索引,3数组本身。
该方法适合筛选一个数组。如上图用例,用filter通过筛选,就选出来了及格的同学了
map() 方法通过对每个数组元素执行函数来创建新数组。
说人话就是映射,把原数组的元素,通过回调函数运算,映射为一个新数组。该方法不修改原数组,只会返回一个return 后的元素组成的新数组。
回调函数接受三个参数:1项目值,2项目索引,3数组本身。
还是以上面的同学举例,通过映射,由原来的对象数组,获得了及格同学名字数组,最后简单运算进行输出。
reduce、reduceRight方法提供了一个叠加器,来用以对数组元素进行迭代运算。前者迭代方式正序,后者则为逆序。该方法不修改原数组,会返回叠加器叠加后的新数据成员。数据成员可以为简单数据成员例如数字、字符串,也可以是数组,或者对象。
按照惯例,介绍参数:
两种方法接受两个参数,第一个是回调参数,第二个参数可选,为叠加器增设一个初始值。该初始值可以为基本数据类型也可以是扩展数据类型。
回调参数接受四个参数,第一个为增设初始值或者上次叠加后的返回值,剩余三个参数分别为2项目值,3项目索引,4数组本身
光看定义可能会有点绕口,下面就用一个简单的例子来看看
这个例子通过累加实现求数组的全体和
回调函数参数列表里可以看到使用了俩,我们通过循环的方式把参数打印出来再看看执行过程
很清晰地看到,reduce第二个参数被作为第一次循环回调的prev传递进去,而每次return的值又被作为下次回调的prev,这样循环往复遍历完数组。
这俩方法能做的事情远不止这些,排序,筛选,映射,去重,计算均分,包括权重均分,reduce和reduceRight都能做,下面就是一个计算均分的小例子
利用reduceRight反向遍历,到数组第“0”项刚好结束,完成计算平均分。
every方法检查所有数组元素是否通过测试。Some方法则检查是否有某些元素通过了测试。该方法不修改原数组,只会返回true或者false。
回调函数接受三个参数:1项目值,2项目索引,3数组本身。
这俩方法很适合用来“寻找异类”,例如every判断是不是每个同学都及格了,some判断有没有同学考了满分。下例分别用every判断是否每个人都及格,some判断是不是有同学考了不该考的59分。
寻找在不在
find方法返回通过测试函数的第一个数组元素的值。返回值为该元素或者undefined(未找到的情况下)。这个方法参数也是一个回调,和上面方法有着类似的三个参数:1项目值,2项目索引,3数组本身。
需要注意的是,和some方法的异同,some返回true/false,而find返回该元素或者undefined,这也就意味着,如果想寻找undefined,不能用find寻找~
findIndex() 方法返回通过测试函数的第一个数组元素的索引。如果未找到则返回-1。除去和上面方法不一样,返回索引(又叫数组下标)以外,其余与上面find方法完全一致。
算是规避了上面不能寻找undefined的尴尬。
indexOf() 方法可返回数组中某个指定的元素位置。该方法参数有两个,1为寻找的元素值,2可选,为开始寻找的位置。如果没有指定则从数组开始寻找。返回值为索引(数组下标)或者undefined(未找到的情况下)。
indexOf和上面的方法是不是感觉很像?indexOf在es5之前就有且浏览器的支持程度都很好,但为什么在es6又添加了findIndex呢:
注意js中对象是不能直接比较的,直接比较都会返回false
如果采用回调的方式,那么不管数组内元素的深度有多深,都可以采用深度比较的方式来判断,而不用转为JSON字符串这种比较消耗性能的方式了。
如下示例,对于对象的比较,find和findIndex有着无与伦比的优势。
includes() 方法用来判断一个数组是否包含一个指定的值,根据情况,如果包含则返回 true,否则返回false。
使用indexof时,一来需要根据位置判断是否存在,产生了arrayObject.indexOf(item)<0这种语义不够清晰的代码,二则是内部使用严格相等的判断没法找到NaN元素,所以在es6中添加了该方法。
看上图示例对NaN的处理,这个需要与indexOf进行辨析。当然也可以用isNaN配合some实现,只是稍微麻烦了些。
数组的剩余常用函数
老生常谈的排序函数,参数传入一个比较函数来进行比较。比较函数可选,接受两个参数,分作作为比较元素传入。如果未传比较函数,则直接按照字符编码的顺序进行排序。
注意sort排序函数会直接在原数组上进行排序,所以如果想不“伤害”原数组,就拿一份拷贝去排序吧。
简单的翻转函数,将原数组进行翻转。无参数,返回数组
同sort,也会直接在原数组上进行排序。
fill() 方法用一个固定值填充一个数组中从起始索引到终止索引内的全部元素。不包括终止索引。
该方法参数有3个,第一个为待填充元素(可省略,省略则填充undefined),第二个为填充开始位置(填写了第一个参数的情况下可省略,默认为数组下标开始位置),第三个参数为填充结束位置(填写了前两个参数情况下可省略,默认为数组结束位置)
哦对了,1,2,3这三个方法均在原数组上修改,返回也均为原数组。
slice() 方法可从已有的数组中返回选定的元素。
该方法参数俩,第一个是截取的开始位置,第二个可选,截取的结束位置,默认为数组末尾。返回则是一个全新的数组,且不修改原数组。
需要注意的是,参数均指数组的下标,且不包含第二个参数位置。
splice() 方法向/从数组中添加/删除项目,然后返回被删除的项目。
该方法参数至少有两个,第一个是开始添加/删除的位置下标,第二个是要删除的元素数量。从第三个参数开始可选,要添加的元素依次向后排列。
返回值则为删除元素构成的数组。
可以看到,该方法可以做到随意的增,删,改,灵活度很高,而且是在原数组上直接修改,使用时应该多加小心。
需要注意,如果没有删除元素(即第二个参数为0),返回的是空数组,配合上空数组转换布尔值为真,那酸爽…
还有点,该方法由于和上面slice名字实在太像了,而且最常用的参数都是俩数字,极其容易搞混,万一碰到如下情况
参数、返回值全都一样,而原数组内部却天差地别,估计排查bug时候会崩溃吧…慎用splice,在生产开发时候,还是用push,pop,shift,unshift四件套,清晰易懂好辨识,谁用谁知道~
该方法就是用来判断是不是数组咯,毕竟typeof数组得到的是Object,所以单独把方法拎出来讲一下。
使用时注意方法定义在Array上,普通的数组用.访问会报错,参数为待判断的对象,返回值就是true、false。
还有,有关空数组的布尔值判断,也是JavaScript坑点之一,网上一搜一大堆,看下图:
怎么样,足够绕吧,这里涉及到各种隐式转换,参照了网上
https://www.cnblogs.com/frostbelt/p/3425498.html
该同学的帖子,具体原理就不展开讲了,可以在这个同学帖子下面留言一起探讨,在这里只是把这个现象贴出来。
还有剩下的for in和for of的用法,由于其不太属于数组特有的循环,改天开贴再写吧,这篇就不展开讲述了(疯狂挖坑…)