您的位置:首页 > Web前端 > JavaScript

javascript引用类型之Array类型

2014-02-27 10:30 267 查看

简介

javascript中数组是无类型的,即数组中的元素可以是任意类型的。而且,javascript中数组是动态的,它们会根据需要调整大小。

数组是对象的特殊形式。

创建数组

创建数组有两种方式。第一种是使用数组直接量,第二种是使用构造函数Array()。例如:

//使用数组直接量
var arr1=["a","b","c"];

//使用构造函数Array()
var arr2=new Array("a","b","c");

//创建空数组
var arr3=[];
var arr4=new Array();


在使用构造函数创建数组时,传递给构造函数的参数不同,将创建不同含义的数组,例如:

var b1=new Array(); //创建空数组
var b2=new Array(20); //创建长度为20的数组
var b3=new Array("a"); //创建第一个元素为字符串“a”的数组
从上面的例子可以看出:不向构造函数传递参数时,将创建一个空数组,这等价于用数组直接量[]创建数组;当向构造函数传递一个数值参数(正整数)时,传入的参数将会作为数组的长度;当向构造函数传递非数值类型的参数时,这个参数会作为数组的值。

数组元素的读写

在读取和设置数组的值时,使用方括号([])来操作。方括号中是基于0的数字索引。

var colors=["red","yellow","blue"];
alert(colors[0]); //red
colors[3]="green"; //向数组中添加一项
向数组设置值时,如果方括号中的数值小于数组中的长度-1,则用新的值代替旧的值;假如等于数组长度,则像数组末尾添加一项,值为传入的参数,数组长度+1;假如大于数组长度,那么数组的长度会自动增加至该索引值+1,数组最后一项值为传入的参数,其他空出的位置,值为undefined。

var b=[1];
alert(b.length); //1
b[0]=2;
b[1]=3;
alert(b); //2,3
alert(b.length); //2
b[3]=6;
alert(b[3]); //6
alert(b[2]); //undefined
alert(b.length); //4


数组长度

每个数组都有个length属性,来表示数组的长度。

数组的length属性是可读写的。如上面提到的,如果为一个数组赋值,他的索引index大于或等于现有数组的长度,该数组的length属性将设置为index+1;如果设置数组的length属性为小于当前长度的一个非负整数n时,当前数组中的那些索引值大于或等于n的元素将被自动删除。

var a=[1,2,3];
alert(a[2]); //3
a.length=2;
alert(a[2]); //undefined
a[3]=5;
alert(a.length); //4


删除数组元素

在javascript中,可以用delete来删除数组元素。但是,执行该操作后,只是将被删除的项值设置为undefined的,并不会改变数组长度。如:

var a=[1,2,3];
alert(a.length); //3
alert(a[1]);  //2
delete a[1];
alert(a[1]); //undefined
alert(a.length); //3
在这里顺便提下,用delete也可以删除对象的属性,但是与删除数组元素不同,使用delete删除的对象属性,是完全被移除了,而不仅仅是将其值设置为undefined。看一个例子:

var a={x:1,y:2};
alert(a.x);  //1
delete a.x;
alert(a.x); //undefined
for(var arg in a){
alert(arg); //y
}


转换方法

所有对象都有toLocaleString()、toString()和valueOf()方法,数组也不例外。

数组的toLocaleString()、toString()和valueOf()方法在默认情况下,都会返回由数组中每个值的字符串形式拼接而成的以逗号分隔的字符串。

var a=[1,2,3];
alert(a.toString()); //1,2,3
alert(a.valueOf()); //1,2,3
alert(a.toLocaleString()); //1,2,3
数组中还有个方法可以将数组转换成为对应的字符串形式,那就是join()方法。该方法默认情况下将返回以逗号分隔的字符串,与调用数组的toLocaleString()、toString()和valueOf()方法相同。但是,join()还可以使用不同的分隔符来构建数组,只需要向改方法传入作为分隔符的字符串即可。例如:

var a=[1,2,3];
alert(a.join()); //1,2,3
alert(a.join("&")); //1&2&3


栈方法

所谓的栈,是一种数据结构,它的特点是【先进后出】,即最新添加的项将被最早删除,并且所有操作只能在栈的顶部进行。

javascript中提供了两个方法,可以模拟实现这样的行为。这两个方法分别为push()和pop()。

push()方法用于在数组的末尾添加元素。它可以接受任意多个参数,将它们逐个添加到数组中,并返回修改后数组的长度。

pop()方法用于移除数组中的最后一项。它不接收参数,直接删除数组最后一项,减少数组的长度,并返回被删除的项。

var colors=["red"];
alert(colors.push("yellow")); //2
colors[2]="blue";
alert(colors); //red,yellow,blue
alert(colors.pop()); //blue
alert(colors.length); //2
alert(colors); //red,yellow


队列方法

队列方法也是一种数据结构,它的特点是【先进先出】,即最早添加的元素也将最早被删除,并且,删除操作在队列前端进行,添加操作在队列末端进行。

前面提到的push()方法已经能够在队列末端添加元素了。实现在队列前端删除元素的方法是shift()方法。它将移除数组的第一项并且返回该项,数组长度减1。结合使用push()方法和shift()方法,就能模拟队列的行为。

var colors=["red"];
colors.push("yellow","blue");
alert(colors.length); //3
alert(colors.shift()); //red
alert(colors); //yellow,blue
alert(colors.length); //2
既然能在数组的末端进行删除、添加操作,也能在数组的前端进行删除操作,那自然,也是可以在数组的前端进行添加操作的。实现这个操作的方法就是unshift()。该方法在数组的前端添加元素,并且返回新的数组长度。结合使用unshift()和pop()方法,可以模拟反向队列。

var colors=["red"];
alert(colors.unshift("blue","yellow","green"));  //4
alert(colors.length); //4
alert(colors.pop()); //red
alert(colors); //blue,yellow,green
alert(colors.length); //3
注意,unshift()操作中的参数是一次性插入数组的,而非一次一个的插入。所以,最终的数组中,插入的元素的顺序和他们在参数列表的顺序是一样的。

重排序方法

数值有两个方法可以实现对它的重新排列。这两个方法分别是reverse()和sort()。

reverse()方法将会对数组进行反转操作。

var a=[1,2,3];
alert(a.reverse()); //3,2,1
alert(a); //3,2,1
默认情况下,sort()方法将对数组进行升序排列。这里要注意的是,在调用sort()方法时,它会根据字符串的比较规则来进行排序,即按照字母表顺序排序。
var a=[1,5,12];
alert(a.sort()); //1,12,5
alert(a); //1,12,5
上面的例子中,在调用sort()方法时,实际上它调用了每个数组像的toString()方法,将它们都转化成字符串,然后对字符串进行比较排序。

若像要得到正确的数值比较结果,可以像sort()方法传入一个比较函数:

function compare(a,b){
if(a>b){
return 1;
}else if(a<b){
return -1;
}else{
return 0;
}
}

var a=[1,5,12];
alert(a.sort(compare)); //1,5,12
alert(a); //1,5,12


操作方法

在这一小节中将介绍三种方法,分别是concat()方法,slice()方法和splice()方法。

concat()方法用于连接两个数组。该方法接收一个参数列表,调用该方法时,会创建一个当前数组的副本,然后再将接收到的参数添加到这个副本的末尾,最后返回新构建的数组。由此可以看出,该方法不会影响原数组。

var a=["red"];
alert(a.concat("yellow")); //red,yellow
alert(a); //red
有一点需要强调下,当传入的参数是一个数组时,concat()方法会将其展开,然后该参数数组的元素添加到副本中,例如:

var a=[1];
var b=a.concat([2,3]);
alert(b[1]); //2
alert(b.length); //3
但是,如果传入的是嵌套数组,它不会将它们逐一展开,例如:

var a=[1];
var c=a.concat([2,[3,4]]);
alert(c[2]); //3,4
alert(c.length); //3
上面的例子,传入concat()方法的参数是嵌套数组[2,[3,4]],其中它的元素2和[3,4]将会被当做两项添加到副本中。

slice()方法用于返回数组的子元素。它有两个参数,第一个参数是要返回项的起始位置;第二个参数是可选的,是要返回项的结束位置。返回的项中,包括起始位置的元素,但不包括结束位置的元素。该方法不会影响原数组。

var a=[1,2,3,4,5];
alert(a.slice(1,3)); //2,3
当只向slice()方法传入一个参数时,该参数表示的是其实位置,将返回由该位置开始到数组末尾的所有项,例如:

var a=[1,2,3,4,5];
alert(a.slice(1)); //2,3,4,5
当向slice()传入负数参数时,可以将改参数跟数组的长度相加,得到的值将作为新的参数传入数组,例如:
var a=[1,2,3,4,5];
alert(a.slice(-3,-1)); //3,4
alert(a.slice(2,4)); //3,4
如果结束位置小于起始位置,则返回空数组。

splice()操作可以用于删除、替换、插入数组元素。它返回被删除的项,如果没有被删除的项,则返回空数组。splice()是在原数组上操作的,会改变原数组。

当splice()用于删除数组元素时,它接收两个参数,第一个参数是要删除的第一项的位置和要删除的项数。其实第二个参数是可选的,如果只传入一个参数,该参数表示要删除的第一项的位置,然后它会删除从这个位置(包含)起后面的所有元素,例如:

var a=[1,2,3,4,5];
alert(a.splice(2,1)); //3
alert(a); //1,2,4,5
alert(a.splice(2)); //4,5
当splice()用于插入元素时,它有三个参数:起始位置,0(因为要删除的元素为0),要插入的元素列表。例如:

var a=[1];
a.splice(1,0,2,3);
alert(a); //1,2,3

当splice()用于替换元素时,它有三个参数:起始位置,要删除的项数,要插入的元素列表。例如:

var a=[1,2,3];
alert(a.splice(1,2,"a","b"));  //2,3
alert(a); //1,a,b


位置方法

indexOf()和lastIndexOf()用于返回要查找项在数组中的位置,如果找不到则返回-1。它们都接受两个参数,一个是要查找的项;另一个是开始查找的位置。

indexOf()方法是从数组的前端开始向后查找的,而lastIndexOf()则是从数组的末端开始向前查找。

var a=["a","b","c","b"];
alert(a.indexOf("b",0)); //1
alert(a.lastIndexOf("b"),3); //3


其他方法

以上是javascript数组比较常用的一些方法。javascript数组还有一些其他方法用于迭代或者缩小数组。比如:every()、filter()、forEach()、map()、some()、reduce()和reduceRight()等方法。这些方法是ECMAscriot5的方法,这里不一一介绍。以后有用到的话,会再深入了解。

多维数组

事实上,javascript不支持真正的多维数组。但是,像文章开头说的,javascript数组是无类型的,它的元素可以是任何类型的值。因此,可以像javascript数组中传入数组当做元素,那么也可以模拟多维数组。例如:

var a=[[1,2],[3,4],[4,5]];
alert(a[1][0]); //3


关联数组

通过字符串来索引的数组,就称为关联数组。

javascript中的对象都是关联数组。(因为可以使用[]来访问对象属性)

在javascript中,任何对象都可以创建任意数量的属性。但是,用点运算来访问属性时,属性名必须直接出现在程序中,程序无法修改它们。即程序无法动态制定一个标识符。

然而使用[]来访问时,属性名是任何可以转换为字符串的表达式,所以程序是可修改的。要动态创建属性时,只能由[]来操作属性名。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息