数组Array与其他语言中的数组都是数据的有序列表,但与其他语言不同的是JavaScript(ECMAScript)数组的每一项可以保存任何类型的数据,也就是说在数组中第一个位置可以存储字符串,第二个位置可以保存数字,第三个位置保存对象,以此类推。而且,数组的大小是可以动态调整的,即可以随着数据的添加自动增长以容纳新增的数据。
下面系统的总结一下数组的一些使用方法。
一、创建数组的基本方式有两种
第一种:使用Array的构造方法
//1、初始化一个数组对象,该数组为空数组
var array = new Array();
//2、Array构造方法接收参数,如果是这个参数是一个数字,会自动生成length属性
var array1 = new Array(30); //数组的length属性为30,array1.length == 30
//3、如果传递给Array方法的参数不是数字,则会生成包含参数的一个数组
var array2 = new Array("one","two");
console.log(array2); // one,two
var array3 = new Array("lala");
console.log(array3); // lala
//4、使用Array构造方法时可以省略new关键字,输出结果相同
var array4 = Array("lala");
console.log(array4); // lala
第二种:使用数组的字面量表示法
var array = []; //创建一个空数组
var array = ["one","two"]; // 创建一个包含 2 个字符串的数组
二、数组的length属性
JavaScript中数组的length属性有一个特性——它不是只读的。通过这个属性,可以从数组的末尾移除项或向数组中添加新项。
//删除项 设置为小于数组项目数的值,删除位置为2的元素
var colors = ["red","blue","green"]; //包含3个元素
colors.length = 2;
console.log(colors[2]); //undefined 数组中index为2即green元素被删除掉了
//增加项 设置为大于数组项目数的值,则新增的每一项都会取得undefined
colors = ["red","blue","green"];
colors.length = 4;
console.log(colors[3]); //undefined
利用length属性可以方便的在数组的末尾添加新元素
var persons = ["xiaoming","xiaohong"]; //创建一个包含2个元素的数组
persons[persons.length] = "小王";
persons[persons.length] = "小李";
console.log(persons); //[xiaoming,xiaohong,小王,小李]
三、检测数组
var arr1 = [1,2,3,4];
Array.isArray(arr1); //返回true
var arr2 = "hello world";
Array.isArray(arr2); //返回false
四、push、pop、unshift、shift 实现栈方法和队列方法
1、栈方法(LIFO:last-In-First-Out的数据结构)
//ESMAScript为数组专门提供了push()和pop()方法,来实现类似栈行为。
//push()方法可以接受任意数量的参数,把他们逐个放在数组末尾,并返回数组的长度
var persons = Array();
var count = persons.push("小王","小明");
console.log(count); //2
//pop()方法是删除数组中最后一位的元素,并返回删除元素的值
var persons = ["小王","小明"]
var person = persons.pop();
console.log(person); //小明
2、队列方法(FILO:First-In-last-Out的数据结构)
a、push()和shift()方法组合
//push()方法是向数组末尾添加元素,而shift()方法能够删除数组中第一个元素,并且返回删除元素的值
var array = ["one","two"];
array.push("three"); //one ,two ,three
var item = array.shift(); //删除并返回数组中的第一项
console.log(array.length); //2
console.log(item); //one
//这样就实现了,先进先出的队列方法
b、unshift()和pop()方法组合
//unshift()方法是向数组前端添加元素,并且返回数组的长度,而pop()方法能够删除数组中最后一个元素,并且返回删除元素的值
var array = ["one","two"];
var count = array.unshift("zero"); //zero,one ,two
console.log(count); //3
var item = array.pop(); //删除并返回数组中的最后一项
console.log(array.length); //2
console.log(item); //two
四、数组排序方法(reverse、sort)
1、reverse()方法,这个方法会简单的反转数组元素顺序
var values = [1,2,3,4,5,6,7];
values.reverse();
console.log(values); //[7,6,5,4,3,2,1]
可以看到这个方法不够灵活,因此才有了sort()方法
2、sort()方法,这个方法的功能就相当强大了
a、默认情况下,sort()方法按照升序排列数组
//为了实现排序,sort()方法会调用每个数组项的toString()转型方法,然后比较得到的字符串,来确定如何排序
//即使数组中的每个元素都是数值,sort()方法比较的也是字符串
var values = [0,1,5,10,15];
values.sort();
console.log(values); //[ 0, 1, 10, 15, 5 ]
//这里得出的结果,并不是按照数值的大小排序的,而是按照字符串的大小来排序
b、sort()方法接收一个比较函数作为参数,以便我们指定哪个值位于哪个值的前面
- 比较函数接收两个参数
- 如果第一个参数应该位于第二个之前则返回一个负数
- 如果两个参数相等则返回0
- 如果第一个参数应该位于第二个之后则返回一个正数
//比较函数(升序) ,如果想要降序将return值反之即可
function compare(value1, value2){
if (value1 < value2) {
return -1;
}else if (value1 > value2) {
return 1;
}else {
return 0;
}
}
var values = [0,1,5,22,10,15];
values.sort(compare); //[ 0, 1, 5, 10, 15, 22 ]
//比较函数的也可以简写如下
//如果value1 > value2 则返回true,说明需要交换两个值的位置
function compare1(value1, value2){
return value1 > value2; //升序
}
//如果value1 < value2 则返回false,这两个值不需要交换位置
function compare2(value1,value2){
return value1 < value2; //降序
}
四、cancat、slice 、splice数组操作方法
1、concat() —— 这个方法可以基于当前数组中的所有元素创建一个新的数组
具体来说,这个方法会先创建当前数组一个副本,然后将接收到的参数添加到这个副本的末尾,最后返回新构建的数组
var numbers = [1,2,3,4];
var numbers2 = numbers.concat(5,6,[7,8]);
console.log(numbers); //[ 1, 2, 3, 4 ]
console.log(numbers2);// [ 1, 2, 3, 4, 5, 6, 7, 8 ] 一个全新的数组,不影响原数组
2、slice() —— 这个方法可以基于当前数组中的一个或者多个元素创建一个新的数组
- 这个方法接收一个或两个参数
- 只有第一个参数:该方法返回该参数指定的位置开始到数组末尾的所有元素
- 两个参数:该方法返回起始和结束位置之间的元素(但不包括结束位置的元素)
- slice方法不影响原始数组
var numbers = [1,2,3,4,5,6,7];
var numbers2 = numbers.slice(3);
var numbers3 = numbers.slice(3,6);
console.log(numbers); //[ 1, 2, 3, 4, 5, 6, 7 ]
console.log(numbers2); //[ 4, 5, 6, 7 ]
3、splice() —— 这个方法有很多用法,主要用途是想数组中任意位置插入元素。以下是几个用法
- 删除: 可以删除任意数量的元素,只需指定两个参数:要删除的第一项的位置、要删除的元素数量
var numbers = [1,2,3,4,5,6,7];
var numbers = [1,2,3,4,5,6,7];
var subNumbers = numbers.splice(2,3); //删除index为2以后的三个元素即3、4、5 ,返回所有删除元素
console.log(numbers); //[ 1, 2, 6, 7 ]
console.log(subNumbers);//[ 3, 4, 5 ]
- 插入: 可以向指定位置插入任意数量的项,只需提供 3 个参数:起始位置、0(要删除的项数)和要插入的项
var numbers2 = numbers.splice(2,0,9,9,9,9);
console.log(numbers); //[ 1, 2, 9, 9, 9, 9, 3, 4, 5, 6, 7 ]
console.log(numbers2); //[] 空数组
- 替换:可以向指定位置插入任意数量的项,且同时删除任意数量的项,只需指定 3 个参数:起 始位置、要删除的项数和要插入的任意数量的项。插入的项数不必与删除的项数相等
var numbers = [1,2,3,4,5,6,7];
var numbers2 = numbers.splice(2,1,9,9); //会删除当前数组位置 2 的项,然后再从位置 2 开始插入字符串 9,9 ,插入两项删除一项
console.log(numbers); //[ 1, 2, 9, 9, 4, 5, 6, 7 ]
console.log(numbers2); //[3] 返回删除的元素
总结: splice方法第一个参数指定操作数组的位置index,第二个参数指定要删除的元素数量number,之后N个参数要在index位置插入N个元素
五、indexOf ,lastIndexOf位置方法
这两个方法都接收两个参数:要查找的元素和查找的起点位置(可选)
indexOf()方法从数组的开头(位 置 0)开始向后查找,lastIndexOf()方法则从数组的末尾开始向前查找。
var numbers = [1,2,3,4,5,4,3,2,1];
console.log(numbers.indexOf(4)); //3 从开头向后查找元素为4的索引为3
console.log(numbers.lastIndexOf(4)); //5 从末尾向前查找元素为4的索引为5
console.log(numbers.indexOf(0)); //-1 数组中找不到值为0的元素,返回-1
console.log(numbers.indexOf(4,4)); //从位置为4开始向后查找,返回5
console.log(numbers.lastIndexOf(4, 4)); //从位置为4开始向前查找,返回3
六、迭代方法
JS中一共定义了5个迭代方法,每个方法都接收两个参数:要在每一项上运行的函数和(可选的)运行改函数的作用于对象---影响this的指向
传入这个方法中的函数接收三个参数:数组元素的值、该元素在数组中的位置、数组对象本身
- every() 和 some() 方法,他们都用于查询数组中的元素是否满足某个条件
- every() 如果该函数对每一项都返回 true,则返回 true。
- some() 如果该函数对任一项返回 true,则返回 true
//every() 传入函数必须每一项都返回true,这个方法才会返回true。即所有元素都要符合条件才能返回true,否则返回false
var numbers = [1,2,3,4,5,4,3,2,1];
var everyResult = numbers.every(function(item, index, array){
return item > 3;
})
console.log(everyResult); //false
//some() 传入函数只要有一项返回true,这个方法就会返回true。即只要有一项符合条件就返回true,全部不符合返回false
var someResult = numbers.some(function(item,index,array){
return item > 3;
})
console.log(someResult); //true
- filter() 方法,他利用指定的函数确认是否再返回的数组中包含某一项。返回该函数会返回 true 的项组成的数组。
//如下利用filter()方法,返回原数组中元素所有数值都大于 2 元素的集合
var numbers = [1,2,3,4,5,4,3,2,1];
var filterResult = numbers.filter(function(item, index, array) {
return item > 2;
})
console.log(filterResult); //[ 3, 4, 5, 4, 3 ]
- map() 方法,这个数组的每一项都是在原始数组中的对应项上运行传入函数的结果。返回每次函数调用的结果组成的数组。
//利用map函数给数组中的每一项乘以 2,然后返回这些乘积组成的数组
var numbers = [1,2,3,4,5,4,3,2,1];
var mapResult = numbers.map(function(item, index, array){
return item * 2;
})
console.log(mapResult); //[ 2, 4, 6, 8, 10, 8, 6, 4, 2 ]
- forEach() 它只是对数组中的每一项运行传入的函数, 这个方法没有返回值, 本质上与使用 for 循环迭代数组一样
var numbers = [1,2,3,4,5,4,3,2,1];
numbers.forEach(function(item , index, array){
console.log(item, index);
})
七、归并方法 reduce()和 reduceRight()
这两个方法都会迭代数组的所有项,然后构建一个最终返回的值。其中,reduce()方法从数组的第一项开始,逐个遍历 到最后。而 reduceRight()则从数组的最后一项开始,向前遍历到第一项。类似于indexOf和lastIndexOf的区别
这个方法接受两个参数:一个是在每一项上调用的函数和(可选的)作为归并基础的初始值
- 函数接收4个参数: 以前一个值、当前值、元素索引、数组对象本身
- 这个函数返回的任何值都会作为第一个参数自动传递给下一项
- 第一次迭代发生在数组的第二项上,因此第一个参数是数组的第一项,第二参数就是数组的第二项
//只有一个函数参数、没有初始值
//第一次迭代发生在数组的第二项上,因此第一个参数是数组的第一项,第二参数就是数组的第二项
var values = [1,2,3,4,5];
var sum = values.reduce(function(prev, cur, index, array){
console.log(index,prev,cur); //index 从1开始
return prev + cur;
});
console.log(sum);//15
//传递初始值
//第一次迭代发生在数组的第一项上,因此第一个参数是传递进去的初始值,第二参数是数组的第一项
var sum = values.reduce(function(prev, cur, index, array){
console.log(index,prev,cur); //index 从0开始
return prev + cur;
},5);
console.log(sum);//20
使用 reduce()还是 reduceRight(),主要取决于要从哪头开始遍历数组。除此之外,它们完全相同。
#end
数组模块总结完成,如有遗漏与bug,欢迎各位大神指正。
参考资料: JavaScript高级程序设计第三版