(第五天)数组
概念
数组是值的有序集合。每个值叫做一个元素,而每个元素在数组中有一个位置,以数字表示,称为索引。
创建数组
(1)使用数组直接量是创建数组最简单的方法,在方括号中将数组元素用逗号隔开即可。
1 var empty = []; //没有元素的数组 2 3 var primes= [2, 3, 5, 7, 11] ; //有5个数值的数组 4 5 var misc = [ 1.1, true, "a" ]; //3个不同类型的元素和结尾的逗号
数组直接量中的值不一定是常量;它们可以是任意的表达式:
1 var base = 1024; 2 3 var table = [base, base+1, base+2, base+3];
如果省略数组直接量中某个值,省略的元素将被赋予undefined值:
1 var count = [1,,3]; //数组有三个元素,中间的那个元素值为undifined 2 3 var undefs = [,,]; //数组有两个元素,都是undifined
(2)通过构造函数Array()是创建数组的另一种方法。可以用三种方式调用构造函数。
(1)调用时没有参数
1 var a = new Array();
该方法创建一个没有任何元素的空数组,等同于数组直接量[]。
(2)调用时有一个数值参数,它指定长度
1 var a = new Array(10);
该技术创建指定长度的数组。当预先知道所需元素个数时,这种形式的Array()构造函数可以用来预分配一个数组空间。注意,数组中没有存储值,甚至数组的索引属性“0”,“1”等还未定义。
(3)显示指定两个或多个数组元素或者数组的一个非数值元素
1 var a = new Array(5, 4, 3, 2, 1, "testing, testing");
【注】事实上数组索引仅仅是对象属性名的一种特殊类型,这意味着JavaScript数组没有“越界”错误的概念。当试图查询任何对象中不存在的属性时,不会报错,只会得到undefined值。类似对象,对于对象同样存在这种情况。
稀疏数组
稀疏数组就是从包含从0开始的不连续索引的数组。通常,数组的length属性值代表数组中元素的个数。如果数组是稀疏的,length属性值大于元素的个数。可以用Array()构造函数或简单地指定数组的索引值大于当前的数组长度来创建稀疏数组。
1 a = new Array(5); //数组没有元素,但是a.length是5 2 3 a = []; //创建一个空数组,length = 0; 4 5 a[1000] = 0; //赋值添加一个元素,但是设置length为1001
【注】当在数组直接量中省略值时不会创建稀疏数组。省略的元素在数组中是存在的,其值为undefined。这和数组元素根本不存在是有一些微妙的区别的。可以用in操作符检测两者之间的区别:
1 var a1 = [,,,]; //数组是[undefined, undefined, undefined] 2 3 var a2 = new Array(3); //该数组中没有元素 4 5 0 in a1 // => true : a1在索引0处有一个元素 6 7 8 0 in a2 // => false : a2在索引0处没有元素
数组常见方法
ECMAScript3中的方法
(1)join()
Array.join()方法将数组中所有元素都转化为字符串并拼接在一起,返回最后生成的字符串。可以指定一个可选的字符串在生成的字符串中来分隔数组的各个元素。如果不指定分隔符,默认使用逗号。如下代码所示:
1 var a = [1, 2, 3]; //创建一个包含三个元素的数组 2 3 a.join(); // => "1, 2, 3" 4 5 a.join("") // => "123" 6 7 var b =new Array(10); //长度为10的空数组 8 9 b.join("-"); // =>"---------" :9个连字号组成的字符串
Array.join()方法是String.split()方法的逆向操作,后者是将字符串分割成若干块来创建一个数组。
(2)reverse()
Array.reverse()方法将数组中的元素颠倒顺序,返回逆序的数组。它采取了替换;换句话说,它不通过重新排列的元素创建新的数组,而是在原先的数组中重新排列它们。
1 var a = [1, 2, 3] 2 3 a.reverse().join() // => "3, 2 , 1",并且现在的a是[3, 2 ,1]
(3)sort()
Array.sort()方法将数组中的元素排序并返回排序后的数组。当不带参数调用sort()时,数组以字母表顺序排序(如有必要将临时转化字符串进行比较)
var a = new Array(banana", "cherry", "apple"); a.sort(); var s = a.join(", "); // s == "apple, banana, cherry"
【注】如果数组包含undifined元素,它们会被排到数组的尾部
为了按照其他方式而非字母表顺序进行数组排序,必须给sort()方法传递一个比较函数。该函数决定了它的两个参数在排好序的数组中的先后顺序。假设第一个参数应该在前,比较函数应该返回一个小于0的值。反之亦然。如果两个值相等则顺序无关紧要。例如,用数值大小而非字符表顺序进行数组顺序排序,代码如下:
1 var a = [33, 4, 1111, 222]; 2 3 a.sort(); //字母表顺序:1111,222, 33, 4 4 5 a.sort(function(a,b){ 6 return a - b; //返回负数、0 、正数 7 }); 8 9 a.sort(function(a,b){ 10 return b-a; //数值大小相反的顺序 11 });
(4)concat()
Array.concat()方法创建并返回一个新数组,它的元素包括调用concat()的原始数组的元素和concat()的每个参数。如果这些参数中的任何一个自身是数组,则连接的是数组的元素,而非数组本身。
1 var a = [1, 2 ,3]; 2 3 a.concat(4, 5); //返回 [1, 2, 3, 4, 5]
(5)slice()
Array.slice()方法返回指定数组的一个片段或子数组。它的两个参数分别指定的开始和结束的位置。返回的数组包含第一个参数指定的位置和所有到但不含第二个参数指定的位置之间的所有数组元素。如果只指定一个参数,返回的数组将包含从开始位置到数组结尾的所有 元素。如参数出现负数,它表示相对于数组中最后 一个元素的位置。例如,参数-1指定到了最后一个元素,而-3指定到了倒数第三个元素。【注】slice()不会修改调用的数组。下面有一些示例:
1 var a = [1, 2, 3, 4, 5]; 2 3 a.slice(0, 3); //返回 [1, 2, 3] 4 5 a.slice(3); //返回 [4, 5] 6 7 a.slice(1, -1) //返回 [2, 3, 4] 8 9 a.slice(-3, -2) //返回 [3]
(5)splice()
Array.splice()方法是在数组中插入或删除元素的通用方法。不同于slice()方法和concat()方法,splice()会修改调用的数组。
splice()能够从数组中删除元素,插入元素到数组中或者同时完成这两种操作。在插入后删除点之后的数组元素会根据需要增加或减小它的索引值,因此数组的其他部分仍然保持连续的。splice()的第一个参数指定了插入和(或)删除的起始位置。第二个参数指定了应该从数组中删除的元素的个数。如果省略第二个参数,从起始点开始到数组结尾的所有元素都将被删除。splice()返回一个有删除元素组成的数组,或者如果没有删除元素就返回一个空数组。例如:
1 var a = [1, 2, 3, 4, 5, 6, 7, 8]; 2 3 a.splice(4); //返回 [5, 6, 7, 8]; a是[1, 2, 3, 4] 4 5 a.splice(1,2); //返回 [2, 3]; a是[1, 4] 6 7 a.splice(1,1); //返回 [4]; a是[1]
(6)push()和pop()
push()和pop()方法允许将数组当做栈来使用。push()方法在数组的尾部添加一个或多个元素,并返回数组新的长度。pop()方法则相反:它删除数组的最后一个元素,减少数组长度并返回它删除的值。【注】两个方法都修改并替换原始数组而非生成一个修改版的新数组。组合使用push()和pop()能够用JavaScript数组实现先进后出的栈
1 var stack = []; 2 3 stack.push(1, 2); // stack:[1, 2] 返回2 4 5 stack.pop(); //stack:[1] 返回2 6 7 stack.push(3); //stack:[1, 3] 返回2
(7)unshift()和shift()
unshift()和shift()方法的行为非常类似push()和pop()方法,不一样的是前者是在数组的头部而非尾部进行元素的插入和删除操作。unshift()在数组的头部添加一个或多个元素,并将已存在的元素移动到更高索引的位置来获得足够的空间,最后返回数组新的长度。shift()删除数组的第一个元素并将其返回,然后把所有随后的元素下移一个位置来填补数组头部的空缺。例如:
1 var a = []; 2 3 a.unshift(1); // a:[1] 返回:1 4 5 a.unshift(22); // a:[22,1] 返回:22 6 7 a.shift(1); // a:[1] 返回:22
下面是ECMAScript中有关数组方法
(8)foreach()
foreach()方法从头至尾遍历数组,为每个元素调用指定的元素。如上所述,传递的函数作为foreach()的第二个参数。然后foreach()使用三个参数调用该函数:数组元素,元素的索引和数组本身。如果只关心数组元素的值,可以编写只有一个参数的函数-额外的参数将忽略。
1 var data = [1, 2, 3, 4, 5]; 2 3 var sum = 0; 4 5 data.foreach(function(value){ 6 sum += value; // => 将每个值累加到sum上 7 }); 8 9 sum // =>15 10 11 data.foreach(function(v, i, a){ 12 a[i] = v +1; 13 }) 14 15 data // =>[2, 3, 4, 5, 6]
(9)map()
map()方法将调用的数组的每个元素传递给指定的函数,并返回一个指定的数组,它包含该函数的返回值。
1 a = [1, 2, 3]; 2 3 b = a.map(function(x) { 4 return x*x; // b是[1, 4, 9] 5 })
传递给map()的函数的调用方式和传递给foreach()的函数的调用方式一样。但传递给map()的函数应该有返回值。【注】map()返回的是新的数组:它不修改调用的数组。如果是稀疏数组,返回的也是相同方式的稀疏数组:它具有相同的长度,相同的缺失元素。