数组是值的有序集合。每个值叫做一个元素,而每个元素在数组中有一个位置,以数字表示,称为索引。
通常,数组的实现是经过优化的,用数字索引来访问数组元素一般比访问常规的对象属性要快很多。
实际上,数组是对象的特殊形式,索引可理解为对象的属性,使用[]访问数组时,索引首先转换为字符串,然后作为属性使用。
(1)数组元素的添加和删除
元素的添加有3种方法:
直接量、push()、unshift(),这3个方法添加元素后都会影响数组的length属性值。
元素的删除有3种方法:
delete、pop()、shift(),这3个方法中只有delete不会影响数组的length属性值,pop()、shift()都会影响length属性值。
var a = [1, 2];
a[2] = 3; // a.length = 3
a.push(4); // 添加 a.length = 4
a.pop(); // 删除 a.length = 3
delete a[1]; // a.length = 3,注意:delete不改变length属性,但是
a[1]元素变成了undefined
(2)数组遍历
for循环
for(var i=0; i < a.length; i++) {
// 跳过元素值为undefined的元素和不存在的元素
if (a[i] == undefined) continue;
}
forEach()
forEach()方法从头至尾遍历数组,为每个元素调用指定的函数。
var data = [1,2,3,4,5];
var sum = 0;
data.forEach(function(value) { sum += value;} );
sum; // => 15
forEach()没有像for循环中使用的相应的break语句。如果要提前终止,可以做放到try/catch中处理:
function foreach(a, f, t) {
try {
a.forEach(f, t);
}
catch(e) {
if(e === foreach.break) return; // 提前终止
else throw e;
}
}
foreach.break = new Error("StopIteration");
由于数组也是对象,所以可以使用for/in对数组进行遍历,但是遍历出的属性会包含继承的属性,所以一般不使用for/in对数组进行遍历。
(3)数组方法
join()
join()方法将数组中的所有元素转化为字符串并连接在一起,返回最后生成的字符串。
不修改原始数组。
var a = [1, 2, 3];
a.join(); // => "1,2,3",默认使用","隔开元素
a.join("&"); // => "1&2&3",指定分隔符
var b = new Array(10); // 空数组
b.join("-"); // => "---------",9个分隔符
reverse()
将数组中的元素颠倒顺序,返回逆序的原始数组引用。修改原始数组。
var a = [1, 2, 3];
a.reverse().join(); // => "3,2,1",此时的a是[3, 2, 1]
sort()
将数组元素进行排序,返回排序后的原始数组引用。默认以字母表顺序进行排序。
修改原始数组。
var a = new Array("a", "b", "c");
a.sort();
var s = a.join(", "); // => "c, b, a",数组a现在是["c", "b", "c"]
concat()
创建并返回一个新数组。不修改原始数组。
var a = [1,2,3];
a.concat(4, 5); // 返回[1,2,3,4,5]
a.concat([4,5]); // 返回[1,2,3,4,5]
a.concat([4,5],[6,7]); // 返回[1,2,3,4,5,6,7]
a.concat(4, [5, [6,7]]);// 返回[1,2,3,4,5,[6,7]]
a.join(); // "1,2,3",原始值不发生改变
slice()
对数组进行切割,并返回一个子数组。第1个参数表示切割的起始索引,第2个参数表示切割结束的索引(返回数组不包含结束索引对应的元素值)。如果没有第2个参数,则表示取值到最后一个索引。正值表示正向索引,负值表示反向索引。
不修改原始数组。
var a = [1,2,3,4,5];
a.slice(0, 3); // 返回[1,2,3]
a.slice(3); // 返回[4,5]
a.slice(-3, -1); // 返回[3,4],反向索引,从倒数第3个到倒数第1个元素
splice()
从数组中删除和插入一些元素。splice()的前2个参数指定了要删除的数组元素,后面的参数指定需要插入的元素。第1个参数表示需要删除元素的起始索引值,第2个参数表示需要删除的个数,如果省略则表示删除起始索引后的所有元素。修改原始数组。
var a = [1,2,3,4,5,6,7,8];
a.splice(4); // 返回[5,6,7,8],a是[1,2,3,4]
a.splice(1,2); // 返回[2,3],a是[1,4]
a.splice(1,1); // 返回[4],a是[1]
push()和pop()
push()在数组的尾部添加一个或多个元素,并返回数组新的长度。pop()则在数组的尾部删除一个元素,并返回弹出的元素值。 修改原始数组。
var stack = [];
stack.push(1,2); // stack:[1,2],返回2
stack.push([1,2]); // stack:[1,2, [1,2]],返回3
stack.pop(); // stack:[1,2],返回[1,2]
unshift()和shift()
与push(),pop()不同,unshift()、shift()在数组的头部进行添加与删除操作。unshift()返回新的数组长度,shift()返回弹出的数组元素。 修改原始数组。
var a = [1];
a.unshift(2); // a:[2, 1],返回2
a.unshift(3, [4,5]); // a:[3, [4,5], 2,1],返回4。
a.shift(); // a:[[4,5], 2, 1],返回3
map()
map()方法为数组的每个元素调用指定的函数,并返回一个数组。
a = [1,2,3];
b = a.map(function(x) {return x*x; }); // b是[1,4,9]
注意:map()返回的是新数组,它不修改原始数组,如果是稀疏数组,返回的也是相同方式的稀疏数月:它具有相同的长度,相同的缺失元素。
filter()
filter()方法为数组的每个元素调用指定的函数,并返回数组的一个子集。
filter()会跳过稀疏数组中缺少的元素,它的返回数组总是稠密的。
a = [5,4,3,2,1];
smallvalues = a.filter(function(x) { return x < 3; });
// smallvalues是[2, 1]
indexOf()和lastIndexOf()
indexOf()和lastIndexOf()搜索整个数组中给定值的元素,返回找到的第1个元素的索引,如果找不到,则返回-1。
第1个参数为需要搜索的值,第2个参数是可选的,指定开始搜索的索引位置。
var a = [0,1,2,1,0];
a.indexOf(1); // =>1: a[1] = 1
a.lastIndexOf(1); // =>3: a[3] = 1
a.indexOf(3); // =>-1: a中没有值为3的元素
注意:使用会修改数组原始值的算法(如,reverse(), sort())操作字符串,会抛出类型错误异常。