原文连接:http://mrzhang123.github.io/2016/08/03/js-Arrayjavascript
在ECMAScript中最经常使用的类型之一就是Array类型,Array类型的方法也有不少,因此在这篇文章中,梳理一下Array类型的方法。前端
新建数组的方法有三种:java
/*方法一*/ var a = new Array(1,2,3); /*方法二*/ var b = [1,2,3]; /*方法三(ES6新增)*/ var c = Array.of(1,2,3);
Array.of()
是ES6中新增的将一组值转换为数组的方法,该方法的出现时为了弥补构造函数Array()
由于参数不一样致使的不一样行为。node
Array() //[] Array(3) //[ , , ] Array(1,2,3) //[1,2,3]
从上面能够看出,只有在参数个数很多于2时候,才会返回新的数组。git
对于一个网页或者一个全局做用域而言,使用instanceof
操做符检测,经过返回的boolean
值能够得出是否为数组,可是这样检测的问题在若是网页中包含两个以上不一样的全局做用域,就会从在两个以上不一样版本的Array构造函数,若是从一个框架向另外一个框架传入一个数组,那么传入的数组与第二个框架中原声建立的数组分别有不一样的构造函数。
在ES5中引入的Array.isArray()
解决了这个问题,但若是在不支持ES5的浏览器中检测数组,则须要些兼容性方法,因此检测数组的方法以下:github
function checkArray(arr) { if(typeof Array.isArray){ return Array.isArray(arr); }else{ return Object.prototype.toString.call(arr)==='[object Array]'; } }
push()
接收任意数量的参数,逐个将其添加至数组末尾,返回修改后的数组的长度数组
unshift()
在数组的前端添加任意个项并返回新数组的长度浏览器
pop()
从数组末尾移除最后一项,返回移除的项数据结构
shift()
移除数组中的第一项并返回该项框架
reverse()
反转数组项的顺序
var values = [1,2,3,4,5]; values.reverse(); console.log(values); // =>5,4,3,2,1
sort()
按照升序排列数组项,可是它在实现排序时会调用每一个数组项的toString()
放法,去比较字符串,因此会出现以下状况
var values = [0,1,5,10,15]; values.sort(); console.log(values); // => 0,1,10,15,5
为了在使用sort()
方法时返回正确的排序,咱们须要给sort()
传入一个比较函数,该比较函数传入两个参数,若是第一个参数应该位于第二个参数以前则返回一个负数,若是两个参数相等返回0,若是第一个参数应该位于第二个参数以后则返回一个正数。
/*升序 降序则更改返回值便可*/ function compare(value1,value2){ if(value1 < value2){ return -1; }else if(value1 > value2){ return 1; }else { return 0; } } var values = [0,1,5,10,15]; values.sort(compare); console.log(values);
对于数值类型或者其valueOf()
方法会返回数值类型的对象类型,可使用一个简单的比较函数
function compare(value1,value2){ return value2 - value1; }
参数:
target(必需):从该位置开始替换数据
start (可选):从该位置开始读取数据,默认为0。若是为负值,表示倒数
end (可选):到该位置前中止读取数据,默认等于数组长度。若是为负值表示倒数
在当前数组内部将指定位置的成员复制到其余位置,会覆盖原来的成员。修改原来的数组造成新的数组
var a = [1,2,3]; var b = a.copyWithin(0); // =>[1,2,3] var c = a.copyWithin(0,1); // =>[2,3,3] var d = a.copyWithin(0,1,2);// =>[2,2,3]
上面例子能够看出,虽然copyWithin
的后两个参数是可选的,可是须要写第二个参数,不然返回的只是原数组自己。
slice()
接受一个或两个参数,要返回的起始位置到结束位置但不包括结束位置项,若是只写一个参数则截取数组到最后。能够接收负数做为参数
splice()
作多能够接收三个参数,分别为起始位置,要删除的项目数,要插入的任意数量的项,同个这三个参数是否传入能够实现删除,插入,替换
var colors =['red','green','blue']; var removed =colors.splice(0,1); //删除第一项 console.log(colors); //green,blue console.log(removed); //redm,返回的数组中只包含一项 removed = colors.splice(1,0,'yellow','orange'); //从位置1开始插入两项 console.log(colors); //green,yellow,orange,blue console.log(removed); //返回的是一个空数组 removed = color.splice(1,1,'red','purple'); //插入两项,删除一项 console.log(colors); //green,yellow,purple,orange,blue console.log(removed); //返回yellow
concat()
这个方法会先建立当前数组的一个副本,而后将接收到的参数添加到这个副本的末尾并返回副本。
var a = [1,2,3]; var b = a.concat('a','b',['c','d','e']); console.log(a); // =>1,2,3 console.log(b);
indexOf()
与lastIndexOf()
用于查找数组中是否有该方法,若是有则返回该元素的位置,不然返回-1
。
可是这个方法有两个缺点:
不够语义化
它内部使用严格等于运算符===
,致使了对NaN
的误判。因此ES7新增includes()
去克服这些缺点。
ES7新增
ES7中新增includes()
方法,用于查找数组老是否包含某个元素,返回布尔值,接受两个参数 要查找的元素 和 查找的起始位置。
参数:一个回掉函数
回调的参数:当前值、当前位置、原数组
find()
方法用于找出第一个符合条件的数组成员。
findIndex()
方法返回第一个符合条件的数组成员的位置,若是全部成员都不符合,则返回-1。
var a = [1,4,-5,10]; a.find((n)=> n<0); // -5 var b = [1,5,10,15]; b.findIndex(function(value,index,arr){ return value > 9; });//=>2
ES5为数组定义了五个迭代方法
每一个方法都接收两个参数:要在每一项上运行的函数和(可选的)运行该函数的做用域对象----影响this
的值。
传入这些方法中的函数会接收三个参数:数组项的值、该项在数组中的位置和数组对象自己。
every():对数组中的每一项运行给定的函数,若是该函数对每一项都返回true
,则返回true
some():对数组中每一项运行给定的函数,若是该函数对任一项返回true
,则返回true
filter():对数组中每一项运行给定的函数,返回该函数会返回true
的项组成的数组
forEach():对数组中的每一项运行给定的函数。没有返回值
map():对数组中的每一项运行给定的函数,返回每次调用的结果组成的数组
该方法能够传递两个参数:化简函数,传递给函数的初始值(可选)。
化简函数的参数:上一次调用回调返回的值,或者是提供的初始值(initialValue),当前被处理的元素,当前被处理的元素的索引,调用 reduce 的数组。
这个方法,能够用于求数组元素的和、积、最大值。
var a = [1,2,3,4,5] /*求和*/ var sum = a.reduce((x,y)=>x+y,0); /*求积*/ var product = a.reduce((x,y)=>x*y,1); /*求最大值*/ var max = a.reduce((x,y)=>(x>y)?x:y);
这个方法的简单用法就是这样,在《javascript高级程序设计》(第三版)中只是介绍了这个用法,可是在《javascript权威指南》(第六版)中提到了reduce
的高级用法。
例1:求任意数目对象的“并集”
/* 返回一个新对象,这个对象同时拥有o和p的属性 若是o和p中有重名属性,使用p中属性 */ function union(o,p){ return extend(extend({},o),p); } var objects = [{x:1},{y:2},{z:3}]; var merged = objects.reduce(union); // =>{x:1,y:2,z:3}
例2:统计字符串中每一个字符出现的重复次数
var arr = 'abcdabcdadbc'; var info = arr.split('').reduce((p,k) => (p[k]++ || (p[k] = 1), p), {}); console.log(info); //=> Object {a: 3, b: 3, c: 3, d: 3}
这两个例子,尤为是第二个例子能够看出,reduce()
并不仅仅只是用于数学计算,在第二个例子中能够明显看出在reduce()
第二个参数传入一个空对象,此时它最终返回的就是一个对象。因为自己传入的初始值是对象,因此返回对象。若是传入一个空数组,则返回数组。因此能够看出,最终reduce()
函数返回什么,取决于第二个参数的形式。
Array.join()
方法将数组中的全部元素都转化为字符串并链接起来,返回最后生成的字符串。能够指定一个可选的字符串在生成的字符串中分隔数组的各个元素,如不指定,默认用逗号隔开。
参数:填充项、填充的起始位置、填充的结束位置fill()
方法用于使用给定的值填充数组。
new Array(3).fill(7); //=>[7,7,7]
该方法接收两个参数要转换的非数组对象,对每一个元素进行处理的方法(可选)
在js中,有不少类数组对象(array-like object)和可遍历(iterable)对象(包括ES6新增的数据结构Set和Map),常见的类数组对象包括document.querySelectorAll()
取到的NodeList,以及函数内部的arguments对象。它们均可以经过Array.from()
转换为真正的数组,从而使用数组的方法。事实上只要对象具备length
属性,就能够经过Array.from()
转换为真正的数组。
var a = { 0:'li', 1:'li', 2:'li', length:3 }; console.log(Array.from(a)); // => ['li','li','li'];
Array.from([1,2,3],(x)=>x*x); // =>1,4,9
//arguments对象 function foo(){ var args = [...arguments]; } //nodelist [...document.querySelectorAll('div')];