js基础(数组)--创建数组、稀疏数组、数组的添加和删除、数组遍历、多维数组

1.创建数组

使用数组直接量是创建数组最简单的方法,在方括号中将数组元素用逗号隔开即可。例如:

var empty=[];//没有元素的数组
var primes=[2,3,5,7,11];//有5个数值的数组
var misc=[1.1,true,"a",];//3个不同类型的元素和结尾的逗号

数组直接量中的值不一定要是常量;它们可以是任意的表达式:

var base=1024;
var table=[base,base+1,base+2,base+3];

它可以包含对象直接量或其他数组直接量:

var b=[[1,{x:1,y:2}],[2,{x:3,y:4}]];

如果省略数组直接量中的某个值,省略的元素将被赋予undefined值:

var count=[1,,3];//数组有3个元素,中间的那个元素值为undefined
var undefs=[,,];//数组有2个元素,都是undefined

数组直接量的语法允许有可选的结尾的逗号,故[,,]只有两个元素而非三个。

调用构造函数Array()是创建数组的另一种方法。可以用三种方式调用构造函数。

1.调用时没有参数:

var a=new Array();

该方法创建一个没有任何元素的空数组,等同于数组直接量[]。

2·调用时有一个数值参数,它指定长度:

var a=new Array(10);

该技术创建指定长度的数组。当预先知道所需元素个数时,这种形式的Array()构造函数可以用
来预分配一个数组空间。注意,数组中没有存储值,甚至数组的索引属性“0”、“1”等还未定义。

3·显式指定两个或多个数组元素或者数组的一个非数值元素:

var a=new Array(5,4,3,2,1,"testing,testing");

以这种形式,构造函数的参数将会成为新数组的元素。使用数组字面量比这样使用Array()构造函数要简单多了。

2.稀疏数组

稀疏数组就是包含从0开始的不连续索引的数组。通常,数组的length属性值代表数组中元素的个
数。如果数组是稀疏的,length属性值大于元素的个数。可以用Array()构造函数或简单地指定数
组的索引值大于当前的数组长度来创建稀疏数组。

a=new Array(5);//数组没有元素,但是a.length是5
a=[];//创建一个空数组,length=0
a[1000]=0;//赋值添加一个元素,但是设置length为1001
后面会看到你也可以用delete操作符来生产稀疏数组。

足够稀疏的数组通常在实现上比稠密的数组更慢、内存利用率更高,在这样的数组中查找元素的时间
与常规对象属性的查找时间一样长。

注意,当在数组直接量中省略值时不会创建稀疏数组。省略的元素在数组中是存在的,其值为
undefined。这和数组元素根本不存在是有一些微妙的区别的。可以用in操作符检测两者之间别:

var a1=[,,,];//数组是[undefined,undefined,undefined]
var a2=new Array(3);//该数组根本没有元素
0 in a1//=>true:a1在索引0处有一个元素
0 in a2//=>false:a2在索引0处没有元素
当使用for/in循环时,a1和a2之间的区别也很明显。

需要注意的是,当省略数组直接量中的值时(使用连续的逗号,比如[1,,3]),这时所得到的数组
也是稀疏数组,省略掉的值是不存在的:

var a1=[,];//此数组没有元素,长度是1
var a2=[undefined];//此数组包含一个值为undefined的元素
0 in a1//=>false:a1在索引0处没有元素
0 in a2//=>true:a2在索引0处有一个值为undefined的元素

3.数组元素的添加和删除

我们已经见过添加数组元素最简单的方法:为新索引赋值:

a=[]//开始是一个空数组
a[0]="zero";//然后向其中添加元素
a[1]="one";

也可以使用push()方法在数组末尾增加一个或多个元素:

a=[];//开始是一个空数组
a.push("zero")//在末尾添加一个元素。a=["zero"]
a.push("one","two")//再添加两个元素。a=["zero","one","two"]

在数组尾部压入一个元素与给数组a[a.length]赋值是一样的。可以使用unshift()方法在数组的首
部插入一个元素,并且将其他元素依次移到更高的索引处。

可以像删除对象属性一样使用delete运算符来删除数组元素:

a=[1,2,3];
delete a[1];//a在索引1的位置不再有元素
1 in a//=>false:数组索引1并未在数组中定义
a.length//=>3:delete操作并不影响数组长度

删除数组元素与为其赋undefined值是类似的(但有一些微妙的区别)。注意,对一个数组元素使用
delete不会修改数组的length属性,也不会将元素从高索引处移下来填充已删除属性留下的空白。
如果从数组中删除一个元素,它就变成稀疏数组。

上面我们看到,也可以简单地设置length属性为一个新的期望长度来删除数组尾部的元素。数组有
pop()方法(它和push()一起使用),后者一次使减少长度1并返回被删除元素的值。还有一个
shift()方法(它和unshift()一起使用),从数组头部删除一个元素。和delete不同的是shift()
方法将所有元素下移到比当前索引低1的地方。

最后,splice()是一个通用的方法来插入、删除或替换数组元素。它会根据需要修改length属性并
移动元素到更高或较低的索引处。

4.数组遍历

使用for循环是遍历数组元素最常见的方法:

var keys=Object.keys(o);//获得o对象属性名组成的数组
var values=[]//在数组中存储匹配属性的值
for(var i=0;i<keys.length;i++){//对于数组中每个索引
    var key=keys[i];//获得索引处的键值
    values[i]=o[key];//在values数组中保存属性值
}

在嵌套循环或其他性能非常重要的上下文中,可以看到这种基本的数组遍历需要优化,数组的长
度应该只查询一次而非每次循环都要查询:

for(var i=0,len=keys.length;i<len;i++){//循环体仍然不变
}

这些例子假设数组是稠密的,并且所有的元素都是合法数据。否则,使用数组元素之前应该先检
测它们。如果想要排除null、undefined和不存在的元素,代码如下:

for(var i=0;i<a.length;i++){
    if(!a[i])continue;//跳过null、undefined和不存在的元素
//循环体
}

如果只想跳过undefined和不存的元素,代码如下:

for(var i=0;i<a.length;i++){
    if(a[i]===undefined)continue;//跳过undefined+不存在的元素
//循环体
}

最后,如果只想跳过不存在的元素而仍然要处理存在的undefined元素,代码如下:

for(var i=0;i<a.length;i++){
    if(!(i in a))continue;//跳过不存在的元素
//循环体
}

还可以使用for/i n循环处理稀疏数组。循环每次将一个可枚举的属性名(包括
数组索引)赋值给循环变量。不存在的索引将不会遍历到:

for(var index in sparseArray){
    var value=sparseArray[index];//此处可以使用索引和值做一些事情
}

for/in循环能够枚举继承的属性名,如添加到Array.prototype中的方法。由于这个原因,在数
组上不应该使用for/in循环,除非使用额外的检测方法来过滤不想要的属性。如下检测代码取其
一即可:

for(var i in a){
    if(!a.hasOwnProperty(i))continue;//跳过继承的属性
//循环体
}

for(var i in a){//跳过不是非负整数的i
    if(String(Math.floor(Math.abs(Number(i))))!==i)continue;
}

ECMAScript规范允许for/in循环以不同的顺序遍历对象的属性。通常数组元素的遍历实现是升
序的,但不能保证一定是这样的。特别地,如果数组同时拥有对象属性和数组元素,返回的属性
名很可能是按照创建的顺序而非数值的大小顺序。如何处理这个问题的实现各不相同,如果算法
依赖于遍历的顺序,那么最好不要使用for/in而用常规的for循环。

ECMAScript 5定义了一些遍历数组元素的新方法,按照索引的顺序按个传递给定义的一个函
数。这些方法中最常用的就是forEach()方法:

var data=[1,2,3,4,5];//这是需要遍历的数组
var sumOfSquares=0;//要得到数据的平方和
data.forEach(function(x){//把每个元素传递给此函数
    sumOfSquares+=x*x;//平方相加
});
sumOfSquares//=>55:1+4+9+16+25

forEach()和相关的遍历方法使得数组拥有简单而强大的函数式编程风格。

5.多维数组

JavaScript不支持真正的多维数组,但可以用数组的数组来近似。访问数组的数组中的元素,只要
简单地使用两次[]操作符即可。例如,假设变量matrix是一个数组的数组,它的基本元素是数值,
那么matrix[x]的每个元素是包含一个数值数组,访问数组中特定数值的代码为matrix[x][y]。这
里有一个具体的例子,它使用二维数组作为一个九九乘法表:

//创建一个多维数组
var table=new Array(10);//表格有10行
for(var i=0;i<table.length;i++)
table[i]=new Array(10);//每行有10列

//初始化数组
for(var row=0;row<table.length;row++){
    for(col=0;col<table[row].length;col++){
        table[row][col]=row*col;
    }
}

//使用多维数组来计算(查询)5*7
var product=table[5][7];//35

你可能感兴趣的:(js基础(数组)--创建数组、稀疏数组、数组的添加和删除、数组遍历、多维数组)