1 概述
JS中的数组是值的有序集合;它是弱类型的,数组中可以含有不同类型的元素。数组元素甚至可以是对象或其他数组
数组的大小:0到2^32-1
索引位置从0开始
如果传入大小在这个范围以外会报错
2 创建数组的方式
- 字面量的方式
- 使用new Array()
- 直接使用Array()也可以。(少用)
//使用字面量的方式创建数组
var arr=['a',1,null,undefined,{name:"cindyHua"}];
//使用构造函数创建数组
var arr1 = new Array('a',1,null,undefined,{name:"cindyHua"});
//使用 Array()创建数组
var arr2 = Array('a',1,null,undefined,{name:"cindyHua"});
//如果Array()里只传入了一个数字n,表示创建一个大小为n的空数组
var arr3 = new Array(5); //创建一个大小为5的空数组 [empty × 5]
3 数组的读写
- 通过数组的索引来读写元素 arr[2];
- 可以用delete arr[index] //删除索引为index的元素
- arr.length-=1 //删除数组末尾的元素
4 元素的增删
- arr.push(item) 在尾部添加元素
- arr.pop() 尾部删除元素
- arr.length 数组的长度
- arr.unshift(item) 在数组的头部添加元素
- shift() 在数组头部删除元素
var arr=[1,2,3];
//删除元素,保留原来的位置 使用delete
delete arr[1];// 删除索引为1的数 数组的长度依旧为3
//删除元素,不保留原来的位置 使用splice
arr.splice(1,1); // 删除索引为1的数 数组的长度为2
5 数组迭代
- 使用 for in
- 使用常规的循环语句
// 使用 for in 遍历
Array.prototype.hi = "hi";
var arr=['hello',',','I','am','cindy','!'];
arr.name="testArr";
for(i in arr){
console.log(arr[i]);
} //hello , I am cindy ! testArr hi
//使用常规循环语句变量 如for循环 while循环
for(let i=0;i<arr.length;i++){
console.log(arr[i]);
} // hello , I am cindy !
注意到有什么不一样了吗??
使用for in迭代数组的时候会
- 遍历对象的属性(包括原型链上的属性) hi
- 不保证遍历的顺序
需要判断是不是自身属性 使用hasOwnProperty()
for(i in arr){
if(arr.hasOwnProperty(i)){
console.log(arr[i]);
} //hello , I am cindy ! testArr
}
6 特殊的数组
- 二维数组
- 稀疏数组
// 二维数组
var arr=[[1,2],[3,4],[5,6]];
//遍历二维数组
for(i=0;i<arr.length;i++){
let row = arr[i];
for(j=0;j<row.length;j++){
console.log(arr[i][j]);
}
} //1 2 3 4 5 6
稀疏数组:不含有从0开始的连续索引,一般length属性值比实际元素个数大
遍历稀疏数组需要用for in 或者判断是否为undefined的方式
// 稀疏数组
var arr2=[1,,,,2,,5,4];
console.log(arr2.length); // 8
//变量稀疏数组
for(i=0;i<arr2.length;i++){
if(arr2[i] !== undefined){
console.log(arr2[i]);
}
} // 1 2 5 4
7 数组的方法
在Array的原型上的常用方法如下
- join(str) 将数组连接为字符串 str为连接符号,字符串类型
- reverse() 将数组颠倒位置 原数组会被修改
- sort() 排序
- concat() 合并数组 原数组不会被修改
- slice() 返回数组的片段 原数组不会修改
- splice() 拼接数组 原数组会被修改
IE9以上可以使用以下方法(ES5)
- forEach() 迭代数组
- map() 对数组进行映射
- filter() 对数组元素进行一些过滤
- every() 对数组元素的判断,每一元素都要符合要求,返回布尔值
- some() 对数组的判断 ,有一个满足就返回true
- reduce()、reduceRight() 关于数组中每相邻两个元素有关操作的时候可以用这两个方法
- indexOf()、lastIndexOf() 返回元素的索引index
Array构造器上的方法
- isArray() 判断是否为数组
7.1 join(str) 将数组连接为字符串
其中的str为连接符,不传如参数则默认连接符为‘, ’逗号
// join() 方法 将数组连接为字符串
var arr=['hello',',','I','am','cindy','!'];
console.log(arr.join()); // hello,,,I,am,cindy,!
console.log(arr.join(' ')); // hello , I am cindy !
//实现重复字符串n次
function repearStr(str,number){
return new Array(number+1).join(str); //创建一个大小为number+1的数组,将数组使用str为连接符连接成字符串,刚好重复number次
}
var str = repearStr('cindy',3);
console.log(str); //cindycindycindy
7.2 reverse() 将数组颠倒位置 原数组会被修改
//reverse() 颠倒数组 会改变原来的数组
console.log(arr.reverse()); //["!", "cindy", "am", "I", ",", "hello"]
console.log(arr); //["!", "cindy", "am", "I", ",", "hello"]
7.3 sort() 排序 会修改原来的数组
- 默认按照字母的顺序排序的
- 按若需要按照其他的方式(比如:数字大小)进行排序需要传入比较函数
// 默认按照字母的顺序排序的
//按若需要按照其他的方式(比如:数字大小)进行排序需要传入比较函数
var arr2 = [1,32,21,5,31];
console.log(arr2.sort()); //[1, 21, 31, 32, 5]
console.log(arr2); //[1, 21, 31, 32, 5]
// 传入比较函数 按数字从小到大排序
arr2.sort(function(a,b){
return a-b;
}); // [1, 5, 21, 31, 32]
console.log(arr2)
// 按照某一属性排序 , {alpha: "Z", number: 0}, {alpha: "B", number: 1}
var arr3 = [{alpha: "Z", number: 0}, {alpha: "A", number: 9},{alpha: "C", number: 1}, {alpha: "A", number: 2},{alpha: "C", number: 1}, {alpha: "B", number: 3}];
//这里按照对象的number的大小排序
arr3.sort(function(a,b){
return a.number - b.number;
})
console.log(arr3);
//可以有排序规则,先按照数据序号再按照数据类型进行排序
var arr4 =[ {alpha: "C", number: 1},
{alpha: "F", number: 1},
{alpha: "D", number: 12},
{alpha: "A", number: 2},
{alpha: "D", number: 2},
{alpha: "B", number: 3},
{alpha: "A", number: 9},
];
// 按数字升序排列,再按照字母排序
arr4.sort(function(a,b){
return a.alpha.localeCompare(b.alpha);
}).sort(function(a,b){
return a.number - b.number
})
console.log(arr4);
排序结果:(先按照数据序号再按照数据类型进行排序)
7.4 concat() 合并数组 不会改变原有的数组
//合并数组 如果参数是数组会展开一层 参数可以是多个数组或者对象,数字,字符串之类的
console.log(arr.concat([1,1,1],[2,2])) // ["!", "cindy", "am", "I", ",", "hello", 1, 1, 1, 2, 2]
console.log(arr.concat([[1,1],1],2)) // ["!", "cindy", "am", "I", ",", "hello", [1, 1], 1]
7.5slice() 返回数组的片段 原数组不会修改
切片的范围 第一个参数表示起始位置 第二个参数表示结束位置
var arr5 = [1,2,3,4,5]
//1表示起始位置 3表示结束位置
console.log(arr5.slice(1,3)); // [2, 3]
//只有一个参数表示结束位置为数组最后的位置
console.log(arr5.slice(1)); //[2, 3, 4, 5]
//参数可以为负数 负数表示从右网往左数的顺序 -1表示最后边的索引位置
console.log(arr5.slice(1,-1)); //[2, 3, 4]
console.log(arr5.slice(-4,-3)); //[2]
7.6 splice() 拼接数组 原数组会被修改
- 第一个参数表示拼接的起始位置
- 第二个参数表示拼接的长度, 返回切下的数组;如果没有第二个参数表示截取到数组末尾的位置为止
- 第三个及以后的元素表示新拼接的元素
var arr5 = [1,2,3,4,5];
console.log(arr5.splice(2)); //[3, 4, 5]
console.log(arr5); //[1, 2]
arr5 = [1,2,3,4,5];
console.log(arr5.splice(2,2)); //[3, 4]
console.log(arr5); //[1, 2, 5]
//拼接新的元素
arr5 = [1,2,3,4,5];
console.log(arr5.splice(1,1,'a','b')); //[2]
console.log(arr5); //[1, "a", "b", 3, 4, 5]
7.7 forEach() 迭代数组
forEach(fn)传入一个函数
- 第一个参数是遍历的当前元素
- 第二个参数是遍历的index
- 第三个参数是指的当前数组
arr5 = [1,2,3,4,5];
arr5.forEach(function(item,index,arr){
console.log("index:"+index+"; item:"+item+"; arr:"+arr);
})
7.8 map() 对数组进行映射
当需要对数组的每一个元素都执行同一系列的操作的时候可以使用这个方法呀。
var newArr = arr5.map(function(item,index,arr){
return item + 10; //将每一项都加10
});
console.log(newArr); // [11, 12, 13, 14, 15]
7.9 filter() 对数组元素进行一些过滤
arr5 = [1,2,3,4,5,6,7,8];
newArr = arr5.filter(function(item,index){
return index%2==0 || item >5;// 过滤条件 index是2的倍数或者值大于5
}); // [1, 3, 5, 6, 7, 8]
7.10 every() 对数组元素的判断,每一元素都要符合要求,返回布尔值
arr5 = [1,2,3,4,5,6,7,8];
console.log(arr5.every(function(item){
return item >5; //每一个数都大于5
})); // false
7.11 some() 对数组的判断 ,有一个满足就返回true
arr5 = [1,2,3,4,5,6,7,8];
console.log(arr5.some(function(item){
return item >5; //有一个数大于5
})); // true
7.12 reduce()、reduceRight() 与数组里两两相邻元素有关的操作
比如计算数组内元素的和,计算数组内的最大值
参数
- 第一个参数为函数 表示两个数之间的操作
- 第二参数为操作开始的初始值,没有第二个参数就使用数组第一个数
// 求和
var sum = arr5.reduce(function(a,b){
return a+b;
});
console.log(sum); // 36
var max = arr5.reduce(function(a,b){
return a >b ? a :b ;
},10); //这里传了第二个参数 第一次是 10 和 1做比较
console.log(max) // 10
reduceRight与reduce的区别就是它的其实位置是数组最后开始的。
7.13 indexOf()、lastIndexOf() 返回元素的索引index
indexOf从头到尾搜索元素,lastIndexOf 表示搜索的方向是从数组的末尾到首部
参数
- 第一个参数表示要找的元素
- 第二个表示搜索的起始位置(可以为负数)
var arr = [1,2,3,2,1];
console.log(arr.indexOf(2)); //1
console.log(arr.indexOf(99)); //没有指定元素 返回-1
console.log(arr.indexOf(1,1)); //4
console.log(arr.indexOf(1,-3));// 4 搜索元素1,从右边数第三个位置开始向右搜索
console.log(arr.lastIndexOf(2))//3 搜索元素2,从右边的第一个位置向左搜索
console.log(arr.lastIndexOf(2,-2))//3 搜索元素2,从右边数第二个位置开始向左搜索
console.log(arr.lastIndexOf(2,-3))//1
7.14 Array.isArray() 判断是否为数组
这个方法是Array构造器上的方法
console.log(Array.isArray(arr)); //true
console.log(Array.isArray('a')); //false
其余判断变量是否为数组的方法:
[] instanceof Array; //true
({}).toString.apply([]) === "[object Array]"; // true
[].constructor === Array;// true;
8 数组 VS对象
相同点
- 都可以继承
- 数组是对象,对象不一定数数组
- 都可以当作对象删除属性
不同点
- 数组自动更新length
- 按索引访问数组常常比访问数组对象属性明显寻索
- 数组对象继承Array.prototype上的大量数组操作方法