js数组是无类型的。数组内元素可以是任意类型。索引范围在0-2^32-2(4294967294,约为42.9亿多)。数组不一定是连续的,根据其是否连续又分为稀疏数组和非稀疏数组两类。每个数组都有length属性,反应数组的长度。
js数组是js对象的特殊形式,可理解为属性值大都为(除length外)数字的特殊对象,此外,js数组又添加了许多针对数组的方法如forEach()、indexOf()等,以及js数组属性独有的length。这样总结说来,可将js数组可看作有特定属性值(数值及length)和特有操作方法的特殊对象。
undefined
。看一些例子即可明白:
//定义了5个元素,第4个未赋值
var arr = [1,2,3,,5];
console.log(arr.length); //5
//访问未赋值及未定义元素都返回undefined
console.log(arr[3]); //undefined
console.log(arr[100]); //undefined
//字符类型的数值也可访问到元素
console.log(arr[1]); //2
console.log(arr['1']); //2
//属性为负值或非数值
arr[-2]=1;
arr['a']='b';
//仍能读取
console.log(arr[-2]); //1
console.log(arr['a']); //b
//长度仍为5,说明非法索引的添加没有改变length属性
console.log(arr.length); //5
数组创建除使用字面量外,还可使用构造函数var arr = new Array()
,效果与var arr = []
相同,所以一般还是使用字面量较简单。
length属性值是可变的,修改length值可扩充或删减数组
var arr2 = [1,2,3,4,5];
arr2.length=10;
console.log(arr2,arr2.length); //[ 1, 2, 3, 4, 5, , , , , ] 10
arr2.length=3;
console.log(arr2,arr2.length); //[ 1, 2, 3 ] 3
Aarray.prototype定义了大量针对数组元素操作的方法,任何数组对象都可以直接使用它们。
总的看来,js数组的添加删除函数大概有:
push
(pop
)、unshift
(shift
)方法在数组的指定位置添删函数,用法也较为简单。而splice
方法则要灵活的多。
准确来说,该方法的声明应该类似为integer push(a ...)
,入参为0个或多个元素,返回值为新数组的长度。
var arr = [1,2,3,4,5];
//在数组尾部添加新元素,并返回数组长度。
console.log(arr.push(0),arr); //6 [ 1, 2, 3, 4, 5, 0 ]
//在数组尾部添加多个元素
console.log(arr.push(1,2,3),arr); //9 [ 1, 2, 3, 4, 5, 0, 1, 2, 3 ]
//即使添加的是数组,仍看作一个元素
var sub = [7,8,9];
console.log(arr.push(sub),arr); //10 [ 1, 2, 3, 4, 5, 0, 1, 2, 3, [ 7, 8, 9 ] ]
//表示添加0个元素
console.log(arr.push(),arr); //10 [ 1, 2, 3, 4, 5, 0, 1, 2, 3, [ 7, 8, 9 ] ]
pop()
删除数组尾最后一个元素,并返回被删除元素,声明类似于integer pop()
,无入参,即其只能删除最后一个元素。
console.log(arr); // [ 1, 2, 3, 4, 5, 0, 1, 2, 3, [ 7, 8, 9 ] ]
console.log(arr.pop()); //[7,8,9]
console.log(arr.pop()) //3
console.log(arr,arr.length); // [1, 2, 3, 4, 5, 0, 1, 2 ]
这两个方法与push()、pop()很相似,只是他们添加、删除的元素在数组首部,注意:调用unshift或shift后,数组其他元素将全部后移,索引将发生改变。
var arr = [1,2,3,4,5];
//unshift()参数、返回值与push()类似,只是作用于数组头
console.log(arr.unshift(1,2,3),arr); //8 [ 1, 2, 3, 1, 2, 3, 4, 5 ]
//shift()参数、返回值与pop()类似,只是作用于数组头
console.log(arr.shift(),arr) // 1 [ 2, 3, 1, 2, 3, 4, 5 ]
splice()方法可同时添加、删除数组,被当作数组添加删除的通用方法。声明类似于splice(index,delCount,e...)
。参数含义如下,返回删除元素组成的数组(未删除则为[]
)。
var arr = [1,2,3,4,5];
console.log(arr.splice(2, 2, 0,0,0)); //[3,4]
console.log(arr); //[ 1, 2, 0, 0, 0, 5 ]
针对数组操作的一般方法js数组也都有提供,这些方法大都能见其名,只其义。需注意的是有些方法改变原数组而有些不。
string join([separator]); //使用指定分割符将数组分割为字符串,不指定则使用","(逗号),此方法显然不影响原数组。
array concat(item ...); //连接另一个数组并返回新数组,不会修改源数组
array slice(from,to); //如其名,返回原数组从索引from(包括)到to(不包括)的子数组序列,不修改源数组。
array reverse(); //将数组元素全部颠倒顺序。 改变原数组
array sort(); //按顺序排序返回排序后的数组
演示:
var arr = [1,2,3,4,5];
//以下两种方式结果一致,即js权威指南所言,
//cancat()不会递归扁平化数组的数组
console.log(arr.concat(1,2,3)); //[ 1, 2, 3, 4, 5, 1, 2, 3 ]
console.log(arr.concat([1,2,3])); //[ 1, 2, 3, 4, 5, 1, 2, 3 ]
//包括第一个参数不包括第二个
console.log(arr.slice(2,4)); // [ 3, 4 ]
console.log(arr.join()); // 1,2,3,4,5
console.log(arr.join('-')); // 1-2-3-4-5
//reverse()改变了原数组
console.log(arr.reverse()); // [ 5, 4, 3, 2, 1 ]
console.log(arr); // [ 5, 4, 3, 2, 1 ]
//sort()改变了原数组
console.log(arr.sort()); //[ 1, 2, 3, 4, 5 ]
console.log(arr); //[ 1, 2, 3, 4, 5 ]
ECMAScript5添加了若干诸如遍历、过滤等更加简洁的新方法,这些新方法大都可以传递函数作为参数,也就是所谓的函数式编程。
这些函数一般第一个参数为函数,且该数组每个元素都会调用一次该函数,函数提供了3个参数:当前数组元素、当前索引及数组本身,可根据需要使用。
举个例子就明白了:
该方法从头至尾遍历数组。声明类似于forEach(func(e,i,arr))
。
var arr = [4,3,2,1];
// 遍历
var a = arr.forEach( function(element) {
console.log(element); // 4 3 2 1
});
//无返回值
console.log(a); // undefined
//遍历时为每个元素加1
arr.forEach( function(element, index,array) {
array[index]=element+1;
});
console.log(arr); // [ 5, 4, 3, 2 ]
其他类似方法参数与forEach()
一致,直接说用法吧
//对每个元素执行一次特定操作,返回修改后的数组
//如上例使用forEach()对数组每个元素的加一操作,它更适合。
map();
//过滤掉不符条件的元素,返回过滤后的数组。
//其返回的数组总是非稀疏数组
filter();
//对数组进行逻辑判定,返回bool值
every()、some();
实例演示:
var arr = [1,2,3,4,5];
var arr_map = arr.map(function(e){
return e*2;
});
console.log(arr_map); // [ 2, 4, 6, 8, 10 ]
var arr_filter = arr.filter(function(e){
return e>3;
});
console.log(arr_filter); //[ 4, 5 ]
//some()指是否至少存在一个元素符合判定
var flag = arr.some(function(e){
return e>4;
});
console.log(flag); //true
//every()指是否所有元素符合判定
var flag2 = arr.every(function(e){
return e>4;
});
console.log(flag2); //false
该方法相对复杂一些,它接收一个函数作为累加器(accumulator),数组中的每个值(从左到右)开始合并,最终为一个值。声明类似:
reduce(callback(previousValue, currentValue, index, array),[initialValue]);
callback为传入函数,initialValue为第一次调用callback的第一个参数。具体含义如下:
array :数组本身
initialValue是非必填的,当不传时,使用数组的第一个元素作为初始值。
示例:
var arr = [1,2,3];
var total = arr.reduce(function(previousValue, currentValue) {
return previousValue + currentValue;
},0);
console.log(total); //6
来分析一下此函数执行,数组有3个元素,即传入的方法执行了3次。
上面方法其实就是求和操作。我们可以利用此函数进行许多操作。
//求积
arr = [2,3,4];
var product = arr.reduce(function(a,b){
return a*b;
},1);
console.log(product); //24
//求最小值
//使用数组第一个元素作为初始值。
arr = [2,4,10,6,9,3];
var min= arr.reduce(function(a,b){
return a>b?b:a;
});
console.log(min); //2
更多关于reduce()请参考
MDN Array.prototype.reduce()
全文完