目录前端
小伙伴们看了一下目录是否是有点惶恐不安啊,10个目录,不要慌接下来回简介19个Array的方法和几个检查数据类型、建立数组的方法,那也不要怕”有司机带路“ 哈哈,废话不说看下文java
前言
除了Object以外,Array类型恐怕是ECMAScript中最经常使用的类型了。并且,ECMAScript中的数组与其余多数语言中的数组有着至关大的区别。ECMAScript数组的每一项能够保持任何类型的数据。也就是说,能够用数组的第一个位置来保持字符串,用第二个位置来保存数值,用第三个位置保存对象,以此类推。并且,ECMAScript数组的大小是能够动态调整的,便可以随着数据的添加自动增加以容纳新增数据。ios
建立方式
数组的建立方式由两种。第一中是使用Array构造函数,以下chrome
var colors = new Array();
复制代码
若是预选知道数组要保存的项目数量,也能够给构造函数传递该数量,而该数量会自动变成length属性的值。例如,下面的代码将建立length值为20的数组编程
var colors = new Array(20);
复制代码
也能够向Array构造函数传递数组中应该包含的项,如下代码建立了一个包含3个字符串值的数组:后端
var colors = new Array('red','blue','green');
复制代码
固然,给构造函数传递一个值也能够建立数组。但这时候问题就复杂一点了,由于若是传递的是数值,则会按照该数值建立包含给定项的数组;而若是传递的是其余类型的参数,则会建立包含那个值只有一项的数组。看下面的例子数组
var colors = new Array(3);//建立一个包含三项的数组
var names = new Array('Greg');//建立一个包含1项,及字符串‘Greg’的数组
复制代码
另外,在使用Array构造函数的时候能够省略new操做符。以下的例子,省略new操做符的结果相同浏览器
var colors = Array(3);// 建立一个包含三项的数组
var names = Array('Greg');//建立一个包含1项,及字符串‘Greg’的数组
复制代码
第二种方式 建立数组的第二种基本方式是使用数组字面量表示法。数组字面量由一对函数组项的方括号表示,多个数值之间能够逗号隔开。以下:bash
var colors = ['red','bule','green'];// 建立一个包含 3 个字符串的数组
var names = [];// 建立一个空数组
var values =[1,2,]// 不要这样!这样会建立一个包含 2 或 3 项的数组
var options = [,,,,,,]// 不要这样!这样会建立一个包含 5 或 6 项的数组
复制代码
以上的代码第一行建立一个包含3个字符串的数组。第二行使用一对空方括号建立一个空数组。带三个展现了在数组字面量的最后一项添加逗号的结果:在IE8及如下的版本中,values会成为一个包含3项的最后一项的值是undefined的数组;在其余的浏览器中,values会成为包含2项的数组。缘由是IE8以及以前的版本中的ECMAScript实现数组字面量方面存在bug。 因为这个bug致使的另外一种状况如最后一行代码所示,改行代码可能会建立包含5项的数组(在IE9+、Firefox、Opera、Safari和Chrome中),也有可能会建立6项数组(IE8以及以前)。在像这种省略值的状况下,每一项都将得到undefained值;这个结果与调用的Array构造函数时传递项数在逻辑上是相同的。可是因为IE的实现与其余浏览器不一致,所以不建议使用这种语法。与对象同样,在使用数组字面量表示法时,也不会调用Array构造函数(除了FireFox3以及更早的版本)
在读取和设计数组的值时,要使用方括号并提供相应值的基于0的数字索引,以下:数据结构
var colors = ['red','blue','green'];// 定义一个字符串数组
alert(colors[0]);// 显示第一项
colors[2]='black';// 修改第三项
colors[3]='brown';// 新增第四项
复制代码
方括号的索引表示要访问的值。若是索引小于数组中的项数,则返回对应的值,就像这个例子中的colors[0]会显示‘red’同样。设置数组的值也是相同的语法,但会替代指定位置的值。若是设置某个的索引超过了数组的项数,救赎例子中的colors[3]所示,数组会自动增长到该索引值加1的长度
数组的项数保存在其length属性中,这个属性始终会返回0或者更大的值,以下面这个例子所示:
var colors = ["red", "blue", "green"]; var names = [];
alert(colors.length); //3
alert(names.length);//0
复制代码
数组length属性颇有特色----它不是只读的。所以,经过设置这个属性,能够从数组的末尾移除项或者向数组中添加新项。请看下面的例子
var colors =['red','blue','green'];
colors.length = 2;
alert(colors[2])//"undefined"
复制代码
这个例子中的数组colors一开始有3个值。将其length属性设置为2会移除最有一项(位置为2的那一项),结果再访问colors[2]就会显示undefined了。若是将其length属性设置为大于该数组项的值,这是新增的每一项都会取得undefined值,以下
var colors = ["red", "blue", "green"]; // 建立一个包含 3 个字符串的数组 colors.length = 4; alert(colors[3]); //undefined
复制代码
在此,虽然colors数组只有3个项,但把它的length属性设置成了4.这个数组不存在位置3,所访问这个位置的值就是undefaind。
利用length属性也能够方便地在数组末尾添加新项,以下:
var colors = ['red','blue','green'];
colors[colors.length]='black';
cplors[colors.length]='brown';
复制代码
因为数组最后一项的索引始终是length-1,所以下一个新项就是length。每当在数组末尾天机一项后。其实length属性就会自动更新,数组的length就是最后一项的索引加一。看下面代码
var colors=['red','blue','green'];
colors[99]='black';
alert(colors.length);// "100"
复制代码
这个例子中,咱们想colors数组的位置99插入一个值,结果数组新的长度是100,位置3到98实际上都是不存在的,因此访问它们都会返回undfined。数组最多能够包含42亿多个项,几乎已经知足任何编程需求,若是添加的项数超过了这个限制值,就会发生异常。而建立你一个初始化大小与这个上限接近的数组,则可能会致使运行时间超长的脚本错误。
检测数组
自从ECMAScript3 作出规定之后,就出现了肯定某个对象是否是数组的经典问题。对于一个网页,或者一个全局做用域而言,使用instanceof操做符就能获得满意的结果:
if(value instanceof Array){
//对数组执行某些操做
}
复制代码
instanceof 操做符的问题在于,它假定只有一个全局执行环境。若是网页中包含多个框架,那实际上存在两个以上不一样的全局执行环境,从而存在两个以上不一样的Array构造函数。若是你从一个框架向另外一个框架传入一个数组,那么传入的数组与第二个框架的数组中原生建立的数组分别具备各自不一样的构造函数。
为了解决这个问题,ECMAScript5新增了Array.isArray()这个方法。这个方法的目的就是最终肯定某个值究竟是不是数组,而无论它是从哪一个全局环境建立的。这个方法的用法以下。
if(Array.isArray(value)){
// 对数组操做
}
复制代码
支持Array.isArray()方法的浏览器有IE9+、FrieFox4+、Safari5+、Open 10.5+和chrome。
转换方法
我们你们都知道全部的对象都具有有 toLocaleString()、toString()和valueOf方法。其中,调用数组的toString()方法会返回由数组中每一个值的字符串拼接而成的一个以逗号分隔的字符串。而调用valueOf()返回的仍是原数组。实际上,为了建立这个字符串会调用数组每一项的toString()方法,看下面的这个例子。
var colors = ['red','blue','green'];
alert(colors.toString());//'red,blue,green'
alert(colors.valueOf())://'red,blue,green'
alert(colors);//'red,blue,green'
复制代码
这里咱们先显示的调用了toString()方法,以便返回数组的字符串表示,每一个字符串表示拼接成了一个字符串,中间以逗号分隔。接着调用valueOf()方法,而最后一行代码直接将数组传递给了alert()。因为alert()要接受字符串参数,因此会在后台调用toString()方法,由此会获得与其直接调用toString()方法相同的结果。
另外,toLocaleString()方法常常会返回与toString()和valueOf()方法相同的值,但也不老是如此。当调用数组的toLocaleString()方法时,它也会建立一个数字值的以逗号分隔的字符串。而与前两个方法惟一的不一样之处在于,这一次为了取得每一项的值,调用的是每一项的toLocaleString()的方法,而不是toString()方法。请看下面的例子。
var person1 = {
toLocaleString:()=>{
return :'Nikolaos';
},
toString:()=>{
return 'Nikolaos'
}
}
var person2 = {
toLocaleString:()=>{
return :'Grigorios';
},
toString:()=>{
return 'Greg'
}
}
var people = [person1,person2];
alert(people);//Nikolaos,Greg
alert(people.toString());//Nikolaos,Greg
alert(people.toLocaleString());//Nikolaos,Grigorios
复制代码
这上面的例子中咱们定义了两个对象:person1和person2.并且还分别为每一个对象定义了一个toString()方法和toLocaleString()方法,这个两个方法返回不一样的值。而后,建立一个包含前定义的两个对象的数组。将数组传递给alert()时,输出结果是Nikolaos,Greg,由于调用数组每一项的toString()方法,一样直接调用toString()的方法获得结果相同。而当调用数组的toLocaleString方法时,输出的结果是Nikolaos,Grigorios,缘由是调用了数组每项的toLocaleString()方法。
数组继承的toLocaleString()、toString()和valueOf()方法,在默认状况下都会以逗号分隔的字符串的形式返回数组项。而若是使用join方法,则可使用不一样的分隔符来构建这个字符串,join()方法只接受一个参数,即用做分隔符的字符串,而后返回包含全部数组项的字符串。看下面的例子
var colors =['red','green','blue'];
alert(colors.join(','))//red,green,blue
alert(colors.join('||'));//red||green||blue
复制代码
在这里,咱们使用join方法重现了toString()方法的输出。在传递逗号的状况下,获得以逗号分隔的数组值。而在最后一行代码中,咱们传递了双竖线符号,结果获得字符串“red||green||blue”。若是不给join()传递参数,或者传递undefined,则使用逗号做为分隔符。IE7及更早的版本会错误的使用字符串“undefinde”做为分隔符。若是数组中某一项的值是null或者undefined,那么该值在join()、toString()、toLocaleString()和valueOf()方法返回的结果中以空字符串表示。
栈方法
ECMAScript数组也提供一种让数组的行为相似于其余数据结构的方法。具体来讲,数组能够表现的想栈同样,后者是一种能够限制插入和删除项的数据够。栈是一种LIFO(last in first out,新进后出)的数据结构,也就是最新添加的项最先被移除。而栈中项的插入(叫作推入)和移除,只发生在一个位置-----栈的顶部。ECMAScript为数组专门提供push()和pop()方法,以便实现相似栈的行为。 push()能够接受任意参数,把它们逐个添加到数组的尾部,并返回当前数组最新的length,而pop则是移除数组末尾一项并减小当前数组的length,并返回移除的哪一项,看代码
var colors = new Array();
var cunt = colors.push('red','green');
alert(count)//2
count = colors.push('black')
alert(count)//3
var item = colors.pop();
alert(item)//'black'
alert(colors.length);// 2
复制代码
以上代码中的数组能够看作栈(代码自己没有任何的区别,而pop()和push()都是数组默认的方法)。首先,咱们使用push()将两个字符串推入数组的末尾,并返回的结果保存在变量count中(值为2)。而后,再推入一个值,而结果仍然保存在count中。由于此时数组中包含3项,因此push()返回3.在调用pop()时,他们会返回数组的最后一项,即字符串“black”。此后,数组中仅剩两项。
能够将栈方法与其余数组的方法连用,就像下面
var colors = ['red','blure'];
colors.push('brown');
colors[3] = 'black';
alert(colors.length);
var item = colors.pop();
alert(item)
复制代码
在此咱们首先用两个值来初始化这个数组。而后,使用push()添加第三个值,载经过直接在位置3上赋值来添加第四个值。而在调用pop()时,该方法返回了字符串“black”,即最后一个添加到数组的值。
队列方法
栈数据结构的访问规则是list in first out LIFO ,而队列的数据结构的访问规则是FIFO(first in first out,先进先出)。队列在列表的末端添加项,从列表的前端移除项。因为push()是项数组吗,末端添加项的方法,所以要模拟队列只需从一个数组前端取得项的方法。实现这一操做的数组方法就是shift(),它可以移除数组中的第一项并返回该项,同时将数组的长度减一。结合shift()和push()方法,能够向使用队列同样使用数组。
var colors = new Array();
var count = colors.push('red','grreen');//2
alert(count);//2
count = colors.push('black');//3
alert(count);//3
var item = colors.shift();//'red'
alert(item);//red
alert(colors.length)//2
复制代码
这个例子首先使用push()方法建立一个包含3中颜色名称的数组。而后使用shift()方法从数组中取得了第一项,即‘red’。在移除第一项以后,‘green’就变成第一选项,‘black’就变成了第二项,数组也只包含两项了。
ECMAScript 还为数组提供了一个unshift()方法。顾名思义,unshift()与shift()的用途是相反的:它能在数组前端添加任意项并返回数组的长度。所以,同时使用unshift()和pop()方法,能够从相反的方向来模拟队列,即在数组的前端添加,从数组的末端移除,以下面的例子所示。
var colors = new Array();
var count = colors.unshift('red','green');
alert(count)//2
count = colors.unshift('black');
alert(count);//3
var item = colors.pop();
alert(item);
alert(colors.length);//2
复制代码
这个例子建立了一个数组并属于unshift()方法前后推入3个值。首先是‘red’和‘green’,而后是‘black’,数组中的顺序是‘black’、‘red’、‘black’。在调用pop()方法时,移除并返回的是最后一项,及‘green’。IE7 及更早的版本对javaScript的实现中存在一个误差,其中unshift()方法老是返回undefined而不是数组的新长度。IE8在非兼容模式下会返回正确的长度值
重排序方法
数组中已经存在两个能够直接用来从新排序的方法; reverse()和sort()。reverse()方法是反转数组的顺序
var arr = [1,2,3,4,5];
arr.reverse()
alert(arr)// 54321
复制代码
数组初始化的时候是[1,2,3,4,5],通过reverse()方法处理后就变成了[5,4,3,2,1]。
在默认的状况下,sort()的方法会按升序来排了数组的每一项------最小值在最前面,最大值排在数组的最后面。为了实现排序,sort()方法会调用数组每一项的的toString()转换方法,而后在比较获得字符串,肯定如何排序,及时数组中的每一项都是数值,sort()方法比较的也是字符串,以下
var values = [0,1,5,10,15];
values.sort();
alert(values)//0,1,10,15,5
复制代码
可见,及时例子中的未排序以前顺序没有问题,可是sort()方法也会根据测试字符串的结果改变原来的顺序。由于数值5虽然小于10.但在进行字符串比较时,’10‘则位于’4‘的前面,因而数组的顺序就被改变了,不用说,这种排序方式在不少状况下都不是最佳方案。所以sort()方法能够接受一个比较函数做为参数,以便咱们定位那个值位于那个值的前面。
比较函数接受两个参数,若是第一个参数应该位于第二个参数则返回一个负数,若是两个参数相等则返回0,若是第一个参数应该位于第二个以后则返回正数,若是不排序就返回0.
function compare(value1,value2){
return value1-value2
}
var values = [0,5,1,18,15];
values.sort(compare);
alert(values)//0,1,5,15,18
复制代码
固然若是想降序的,我们须要把compare的 return value1-value2换成 return value2-value1
function compare(value1,value2){
return value2-value1
}
var values = [0,5,1,18,15];
values.sort(compare);
alert(values)//18,15,5,1,0
复制代码
固然我们也能够在简化一下上面的代码
var values = [0,5,1,18,15];
values.sort((value1,value2){
return value2-value1
});
alert(values)//18,15,5,1,0
复制代码
reverse()和 sort()方法的返回值是通过排序以后的数组。原数组也会放生改变
操做方法
ECMAScript为了操做已经包含在数组中的项提供了不少的方法。其中,concat()方法能够基于当数组中的全部项建立一个新数组。具体来讲,原数组不改变,会建立一个新的数组副本,而后将接受的参数添加到这副本的末尾,最后返回新构建的数组。没有给concat传递参数的就会建立当前数组的副本,若是传递给concat()方法的是一个或者多个数组,则该方法会将这些数组中的每一项都添加到结果的数组中。若是添加的不是数组,这些值就会被简单的添加到结果数组的末尾。下面一个例子
var colors = ['red','green','blue'];
var colors2 = colors.concat('yellow',['black','brown']);
alert(colors); //red,green,blue
alert(coloes2);// red,green,blue,yellow,black,brown
复制代码
concat(),使用的特色以下
能够传入多个参数
原数组不会发生改变
返回一个新的合并后的结果数组(copy的原数组+每项参数)
slice()方法,它可以基于当前数组中的一或者多项建立一个新的数组。slice()方法能够接受一或者两个参数,既要返回项的起始值和结束位置。在只有一个参数的状况下,slice()方法会返回从该参数指定位置开始到当前数组末尾的全部项。若是有两个参数,该方法返回起始位置和结束位置之间的项,可是不包含结束位置的项,slice()方法不会影响原始的数组。若是 slice()方法的参数中有一个负数,则用数组长度加上该数来肯定相应的位 置。例如,在一个包含 5 项的数组上调用 slice(-2,-1)与调用 slice(3,4)获得的 结果相同。若是结束位置小于起始位置,则返回空数组看例子
var arr = [1,2,3,4,5,6,7,8];
var arr2 = arr.slice(1);
var carr3 = arr.slice(1,4);
var arr4 = arr.slice(-2,-1)===arr.slice(6,7);
var arr5 = arr.slice(-1,-2)
var arr6 = arr.slice(8,1)
var arr7 = arr.slice();
var arr8 = arr.slice(0);
alert(arr2) // 2,3,4,5,6,7,8
alert(arr3) // 2,3,4
alert(arr4) // 6
console.log(arr5) // []
console.log(arr6) // []
console.log(arr7) // [1,2,3,4,5,6,7,8]
console.log(arr8) // [1,2,3,4,5,6,7,8]
alert(arr) // 1,2,3,4,5,6,7,8
复制代码
使用slice的特色
下面我们看看在数组最灵活而且最复杂的一个方法 splice(),它有不少种用途,splice主要用于向数组中途插入项,可是用这种方法的方式有下面三种
splice()方法始终都会返回一个数组,该数组中包含原始数组中删除的项(若是美欧删除任何项,则返回一个空的数组)。下面代码针对增删改的实例
var arr = [1,2,3,4,5]
var removed = arr.splice(0,1);//从位置0 开始删除,删除一项
alert(arr)// 2,3,4,5
alert(removed)// 1
removed = arr.splice(0,0,0,1)//
从位置0开始删除,删除0项,从位置0开始插入,插入两项
alert(arr)//0,1,2,3,4,5
alert(removed)//''
removed = arr.splice(0,2,0,1,2)//
从位置0开始删除,删除0项,从位置0开始插入,插入两项
alert(arr)//0,1,2,2,3,4,5
alert(removed)//0,1
复制代码
位置方法
ECMAScript为数组添加了两个位置方法:indexOf()和lastIndexOf()。这两个方法都接受两个参数:要查找的项和(可选的)表示查找起点的索引。其中,indexOf()方法从数组的开头(位置0)开始向后查找,lastIndexOf方法则从数组的末尾开始相前查找。
这两个方法都返回要查找项在数组中的位置,或者没有找到的状况下返回-1.在比较第一个参数与数组中的每一项时,会使用全等于操做符;也就是说,要求查找的项必须严格相等(===),下面的例子
var number = [1,2,3,4,5,4,3,2,1];
alert(number.indexOf(4))//3
alert(number.lastIndexOf(4))//4
alert(number.indexOf(4,4))//4
alert(number.lastIndexOf(4,4))//3
var person = {name:'Nicholas'};
var people =[{name:'Nicholas'}];
var morePeople=[person];
alert(people.indexOf(person));//-1
alert(morePeople.indexOf(person));//0
复制代码
使用indexOf()和lastIndexOf()方法查找特定项在数组中的位置很是简单,支持它们的浏览器包含IE9+ Firefox2+ safari 3+ Opera9.5+和Chrome。
indexOf()方法的特色和属性
迭代的方法
ECMAScript5 为数组定义了5个迭代的方法。每一个方法都会有两个参数;要在每一项上运行的函数和(可选的)运行该函数的做用域---影响this的值。传入这些方法中的函数会接受三个参数;数组项的值、该项在数组中的位置,数组对象自己。根据使用的方法不一样,这个函数执行后的返回值也是不一样的,看下面五个方法的做用
以上的方法都不会修改原数组。 这些方法中最为类似的是every()和some(),它们都用于查询数组中的项是否知足某个条件。对every()来讲,传入的函数必须对没一项都返回true,这个方法才会返回true;不然,它们就会返回false。而some()方法则是只要传入函数对数组中的某一项返回true,就会返回true。
var numbers = [1,2,3,4,5,6,7];
var everyResult = numbers.every((item,index,arry)=>(item>2));
alert(everyResult);// false
var someResult = numbers.some((item,index,arr)=(item>2))
alert(someResult);//true
复制代码
看一下 filter()方法,它利用指定的函数肯定是否在返回的数组中包含某一项。例如,要返回一个全部数值都大于2的数组,可使用一下代码。
var numbers = [1,2,3,4,3,2,1];
var filterResult = numbers.filter((item,index,array)=>(item>2))
alert(filterReault);//[3,4,3]
复制代码
map()方法也会返回一个数组,而这个数组的每一项都是在原始数组中的对于项上运行传入函数的结果。例如,能够给数组中的每一项乘以2,而后返回这些乘积的数组,以下所示。
var numbers = [1,2,3,4,5,6];
var mapRes = numbers.map((item,index,array)=>(item*2))
alert(mapRes);//[2,4,6,8,12]
复制代码
forEach()方法,它只对是对象数组中的每一项运行传入函数执行。这个方法没有返回值,本质上与使用for循环迭代数组同样。看一例子。
var numbers = [1,2,3,4,5,6];
numbers.forEach((item,index,array)={
// 执行某些操做
})
复制代码
这些数组的方法经过执行不一样的操做,能够大大方便处理数组的任务。支持这些迭代方法的浏览器有IE9+、Firefox2+、Safari3+、Opera9.5+和chrome。
递归方法
ECMAScript5 还新增了两个递归数组方法:reduce()和reduceRight()。这两个方法都会迭代数组的全部项,而后构建一个最终返回的值。其中,reduce()方法从数组的第一项开始,逐个遍历到最后。而redurceRight()则从数组的最后一项开始,向前遍历到第一项。
这两个方法都会接受两个参数;一个在每一下上调用的函数和(可选的)做为递归基础的初始值。传给reduce()和redurceRight()函数接受4个参数:前一个值、当前值、项的索引和数组对象。这个函数返回的任何值都会做为第一个参数自动传递给下一项。第一次迭代发生在数组的第二项上,所以第一个参数是数组的第一项,第二个参数就是数组的第二项。
使用reduce()方法能够执行求数组中全部值以后的操做
var values = [1,2,3,4,5];
var sum = values.reduce((prev,cur,index,array)=>(prev+cur))
alert(sum) ;// 15
复制代码
第一次执行回调函数,prev是1,cur是2。第二次,perv是3(1+2的结果),cur是3(数组的第三项)。这个过程会持续到把数组中的每一项都访问一遍,最后返回结果。
reduceRight()的做用相似,只不过方向相反而已。看一下面的例子
var values = [1,2,3,4,5];
var sum = values.reduceRight((prev,cur,index,array)=>(prev+cur))
alert(sum)//15
复制代码
在这个例子中,第一次执行回调函数,prev是5,cur是4.固然,最终结果相同,由于执行的都是简单相加的操做。
使用redurce和redurceRight(),主要的差异是从那头开始遍历。
数组的方法大概有22个,小伙伴们都记住了吗,接下来一一列出来