数组是值得有序集合。每个值叫做元素,每个元素在数组中都有数字位置编号,也就是索引。
JS中的数组是弱类型的,数组中可以含有不同类型的元素。
数组元素甚至可以是对象或其它数组。
var arr = [1,true,null,undefined,{x:1},[1,2,3]];
创建数组
1.字面量
注意,数组可以用逗号留空的方式创建,如:
var commasArr1 = [1,,2]; //1,undefined,2
var commasArr2 = [,,];//undefined * 2
数组大小限制
size form 0 to 2^23 - 1
2.new Array
var arr = new Array();
var arrWithLength = new Array(100); //undefined * 100
var arrLikesLiteral = new Array(true,false,null,1,2,"hi");
//等价于[true,false,null,1,2,"hi"];
数组元素读写
var arr = [1,2,3,4,5];
arr[1]; //2
arr.length; //5
arr[5] = 6;
arr.length; //6
delete arr[0]; //表现上只是改写为undefined,但是和直接赋值不同
arr[0]; //undefined
arr.length; //6
数组元素增删
动态的,无需指定大小,数组的length会根据数组动态变化
var arr = [];
arr[0] = 1;
arr[1] = 2;
arr.push(3);
arr; //[1,2,3]
arr[arr.length] = 4; //equal to arr.push(4);
arr; //[1,2,3,4]
arr.unshift(0);
arr; //[0,1,2,3,4];
delete arr[2];
arr; //[0,1,undefined,3,4]
arr.length; //5
2 in arr; //判断索引存不存在 false
注:用delete变成的undefined和直接用arr[2] = undefined,是不同的
后者 2 in arr; //true;
arr.length -= 1;
arr; //[0,1,undefined,3],4 is removed
arr.pop(); //3 returned by pop
arr;//[0,1,undefined],3 is removed
arr.shift(); //0 returned by shift
arr; //[1,undefined]
数组迭代
var i = 0,n = 10;
var arr = [1,2,3,4,5];
for(; i < n; i++){
console.log(arr[i]); //1,2,3,4,5
}
for(i in arr){
console.log(arr[i]); //1,2,3,4,5
}
注:如果用 for-in 的方式来循环数组的话,那么在原型链上的属性也会被迭代出来,如:
Array.prototype.x = 'inherited';
for(i in arr){
console.log(arr[i]); //1,2,3,4,5,inherited
}
此时可以用hasOwnProperty()方法来判断是否是数组元素
for(i in arr){
if(arr.hasOwnProperty(i)){
console.log(arr[i]);//1,2,3,4,5
}
}
注:for-in循环是不保证顺序的!
二维数组
var arr = [[0,1],[2,3],[4,5]];
var i = 0, j = 0;
var row;
for(; i < arr.length; i++){
row = arr[i];
console.log('row' + i);
for(j = 0; j < row.length; j++){
console.log(row[j]);
}
}
稀疏数组
稀疏数组并不含有从0开始的连续索引。一般length属性值比实际元素个数大。
var arr1 = [undefined];
var arr2 = new Array(1);
0 in arr1; //true
0 in arr2; //false
arr1.length = 100;
arr1[99] = 123;
99 in arr1; //true
98 in arr1; //false
var arr = [,,];
0 in arr; //false
数组方法
数组的原型 [] => Array.prototype
1.Array.prototype.join
将数组转为字符串
var arr = [1,2,3];
arr.join(); //"1,2,3"
arr.join("_");//"1_2_3"
function repeatString(str,n){
return new Array(n+1).join(str);
}
repeatString("a",3); //"aaa"
repeatString("Hi",5); //"HiHiHiHiHi"
2.Array.prototype.reverse
将数组逆序(原数组变)
var arr = [1,2,3];
arr.reverse(); //[3,2,1]
arr; //[3,2,1] 原数组被修改!
3.Array.prototype.sort
排序(默认是按照字母排序,原数组变)
var arr = ["a","d","c","b"];
arr.sort(); //["a","b","c","d"]
arr = [13,24,51,3];
arr.sort(); //[13,24,3,51] 转换成字符串,按开头数字排序
arr; //[13,24,3,51] 原数组被修改!
/* 数字排序 */
arr.sort(function(a,b){
return a - b;
}) //[3, 13, 24, 51]
/* 对象排序 */
arr = [{age:25},{age:39},{age:99}];
arr.sort(function(a,b){
return a.age - b.age;
})
arr.forEach(function(item){
console.log('age',item.age);
}) //age 25 age 39 age 99
4.Array.prototype.concat
数组合并(原数组不变)
var arr = [1,2,3];
arr.concat(4,5); //[1,2,3,4,5]
arr; //[1,2,3] 原数组未被修改!
arr.concat([10,11],13); //[1,2,3,10,11,13]
arr.concat([1,[2,3]]); //[1,2,3,1[2,3]]
注:当合并的为数组时,会拉平成元素,但合并的数组中还有数组的话,不能拉平数组中的数组
5.Array.prototype.slice
返回部分数组(原数组不变)
var arr = [1,2,3,4,5];
arr.slice(1,3); //[2,3] 左闭右开
arr.slice(1); //[2,3,4,5] 一个参数,从索引开始到最后
arr.slice(1,-1); //[2,3,4] 负数索引,从后往前数,最后一个为-1
arr.slice(-4,-3); //[2]
6.Array.prototype.splice
数组拼接(原数组变)
var arr = [1,2,3,4,5];
/* 一个参数:索引 */
arr.splice(2); //returns [3,4,5]
arr; //[1,2]
arr = [1,2,3,4,5];
/* 两个参数:索引 | 个数 */
arr.splice(2,2); //returns [3,4]
arr; //[1,2,5];
arr = [1,2,3,4,5];
/* 多个参数:索引 | 个数 | 待插入元素 */
arr.splice(1,1,'a','b'); //returns [2]
arr; //[1,"a","b",3,4,5]
7.Array.prototype.forEach
数组遍历
var arr = [1,2,3,4,5];
arr.forEach(function(x, index, a){
console.log(x + '|' + index + '|' + (a === arr));
})
8.Array.prototype.map
数组映射(原数组不变)
var arr = [1,2,3];
arr.map(function(x){
return x + 10;
}); //[11,12,13]
arr; //[1,2,3]
9.Array.prototype.filter
数组过滤(原数组不变)
var arr = [1,2,3,4,5,6,7,8,9,10];
arr.filter(function(x, index){
return index % 3 === 0 || x >= 8;
});// returns [1,4,7,8,9,10]
arr; //[1,2,3,4,5,6,7,8,9,10]
10.Array.prototype.every & some
数组判断
var arr = [1,2,3,4,5];
arr.every(function(x){
return x < 10;
}); //true
arr.every(function(x){
return x < 3;
}); //false
arr.some(function(x){
return x === 3;
}); //true
arr.some(function(x){
return x === 100;
}); //false
11.Array.prototype.reduce & reduceRight
var arr = [1,2,3];
var sum = arr.reduce(function(x, y){
return x + y;
},0); //6
arr; //[1,2,3]
arr = [3,9,6];
var max = arr.reduce(function(x, y){
console.log(x + "|" + y);
return x > y?x:y;
});
// 3 | 9
// 9 | 6
max; //9
注:计算逻辑,当有第二个可选参数时,也就是上面的0,第一次计算 0+1,第二次将上一次结果1和数组中第二个元素相加,第三次将上次结果和下一个元素相加;若没有第二个参数,则第一次取前两个,所得结果和下一个元素进行下一次运算
max = arr.reduceRight(function(x, y){
console.log(x + "|" +y);
return x > y?x:y;
});
// 6 | 9
// 9 | 3
max; //9
注:从右向左传参
12.Array.prototype.indexOf & lastIndexOf
数组检索
var arr = [1,2,3,2,1];
//查找元素2
arr.indexOf(2); //1
//查找元素99
arr.indexOf(99); //-1
//查找元素1,从第二个元素开始
arr.indexOf(1,1); //4
//查找元素1,从倒数第三个元素开始
arr.indexOf(1,-3); //4
//查找元素2,从最后一个元素开始
arr.indexOf(2,-1); //-1
//查找元素2,从右向左找
arr.lastIndexOf(2); //3
//查找元素2,从右向左找,从倒数第二个元素开始
arr.lastIndexOf(2,-2); //3
//查找元素2,从右向左找,从倒数第三个元素开始
arr.lastIndexOf(2,-3); //1
注:不知道看到上面这8个示例是不是晕了,理一理:
①两个方法都可以接收两个参数,第一个为要查找的元素(必选),第二个为开始位置索引(可选)
②所得结果为元素的索引(也称下标),正数即索引(无论怎么找,都是从左向右,从0开始!),-1即未找到
③方法的第二个参数:若为正数,从前往后索引(0开始);若为负数,从后往前索引(-1开始)
13.Array.isArray
判断是否为数组
Array.isArray([]); //true
//另外几种
[] instanceof Array; //true
({}).toString.apply([]) === '[object Array]'; //true
[].constructor === Array; //true (这种不可靠,如继承)
数组小结
数组 VS 一般对象
相同:都可以继承。数组是对象,对象不一定是数组。都可以当做对象添加删除属性。
不同:数组自动更新length。按索引访问数组常常比访问一般对象属性明显迅速。
数组对象继承Array.prototype上的大量数组操作方法
字符串和数组
字符串可以理解为类数组,但它不是数组
var str = "hello world";
str.charAt(0); //"h"
str[1]; //e
Array.prototype.join.call(str,"_");
//"h_e_l_l_o_ _w_o_r_l_d"
博客地址:js不完全入门之数组
欢迎交流指正~
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。