Array类型应该是 ECMAScript 中最常用的类型之一了,并且它定义的数组与其他语言有着相当大的区别。数组是数据的有序集合,我们可以通过下标对指定位置的数据进行读写;特别的是,在 ECMAScript 中,数组的每一项可以保存任何类型的数据,数组的大小可以动态调整,它可以随着数据的添加自动增长来容纳新增的数据,从而变得更加灵活。下面总结了Array类型常见的一些方法。
一、栈方法
push() , pop() 这两个方法可以使数组的行为类似于“栈”这种数据结构,“栈”是一种 LIFO (Last-In-First-Out)后进先出的数据结构。
1.1 push()
- 参数:任意数量的元素;
- 作用:逐个添加到数组末尾;
- 返回值:修改后的数组的长度;
1.2 pop()
- 参数:无;
- 作用:移除数组的最后一项,减少数组的length值;
- 返回值:被移除的项;
let arr = ["hello", "world", "Jingan"]; let length = arr.push("!", 1, "China");
console.log(length); //
console.log(length === arr.length); // true let deleteItem = arr.pop();
console.log(length === arr.length); //false
console.log(deleteItem); // "China"
console.log(arr.length); //
push(),pop()
二、队列方法
队列”这种数据结构的访问规则是 FIFO (First-In-First-Out先进先出),队列列表的末端添加元素,从列表的从头部开始删除。
我们已经知道 push() 可以向数组的末端添加元素,结合方法 shift() 便可以将一个数组的操作模拟成队列。
2.1 shift()
- 参数:无;
- 作用:移除数组的第一项并返回该值;
- 返回值:被移除的项;
除此之外,还有一个 unshift() 方法,使用该方法和 pop() 方法组合可以将数组从相反的方向来模拟队列,即在数组顶端(index=0)添加元素,从数组末端移除元素。
2.2 unshift()
- 参数:任意数量的元素;
- 作用:逐个添加到数组头部;
- 返回值:修改后的数组的长度;
let fruits = ["apple", "orange", "banana"];
console.log(fruits.length); // // 正向队列
let count = fruits.push("grape", "watermelon"); // 推入两项
console.log(count); // let item = fruits.shift(); // 移除第一项
console.log(item); // "apple"
console.log(fruits.length); // // 反向队列
let colors = new Array();
let count_2 = colors.unshift("blue", "red", "black"); // 推入三项
console.log(count_2); // count_2 = colors.unshift("white");
console.log(count_2); // let item_2 = colors.pop();
console.log(item_2); // "balck"
console.log(colors.lenght);
shift(), unshift()
三、重排序方法
3.1 reverse()
- 参数:无;
- 作用:将数组反转,原数组发生改变;
- 返回值:返回反转后的数组;
var arr = [1, 3, 5, "apple", 34];
arr.reverse();
console.log(arr); // [34, "apple", 5, 3, 1]
reverse()
3.2 sort()
默认情况:sort() 方法按升序排列数组项,sort() 方法会调用每个数组项的 toString() 方法,然后比较依次字符串的 unicode 编码值。
var arr = [1, 3, 5, "apple", 34];
arr.sort();
console.log(arr); // [1, 3, 34, 5, "apple"]
sort()
这样比较会产生问题,所以通常情况下,我们常常将一个比较函数传递给 sort() 方法,以便我们自定义比较的方式。
比较函数传递两个参数:first, second;
- 如果 first 应该在 second 之前则返回负数;
- first 与 second 相等返回 0;
- first 应该在 second 后面则返回正数;
function compare(first, second) {
// return first - second; // 升序
return second- first; // 降序
} var arr = [11, 3, 53, 1, 34];
console.log(arr.sort(compare)); // [53, 34, 11, 3, 1]
sort()
四、操作方法
4.1 concat()
该方法首先会创建一个当前数组的复本,然后将接受到的参数添加到这个复本的末尾。最后返回新构建的数组;注意原来那个数组是没有改变的,我们所做的改变都是在原数组的复本上进行操作的
let arr = [1, 2, 3];
let arr_2 = arr.concat(4, [2, 4, 5]);
console.log(arr); // [1, 2, 3]
console.log(arr_2); // [1, 2, 3, 4, 2, 4, 5]
concat()
4.2 slice()
基于当前数组来创建指定的新数组。起始和结束位置作为参数,注意该方法也不会影响原数组。
- 一个参数: 返回参数指定的开始位置到数组末尾的所有项;
- 两个参数: 返回起始位置到结束位置(不包括结束位置)范围内的所有项;
let arr = ["apple", "orange", "banana", "srawberry", "watermelon"];
let arr_01 = arr.slice(2);
let arr_02 = arr.slice(1, 3);
console.log(arr_01); // ["banana", "srawberry", "watermelon"]
console.log(arr_02); // ["orange", "banana"]
slice()
4.3 splice()
这个方法应该是最强大的数组方法了吧,并且还没有之一。主要有三种用途:
- 删除:可以删除任意数量的项,两个参数:要删除的第一项的位置和要删除的个数。
- 插入:可以向数组中插入任意数量的项,至少三个参数:起始位置、0(要删除的项数)、要插入的项。如果要插入多个项,可以在继续传入参数。
- 替换:可以向指定位置删除任意数量的项,并且同时插入任意数量的项。
注意splice()方法始终都会返回一个数组,该数组中包含从原数组中删除的项(若没有删除,则返回空数组)。
let arr = ["apple", "orange", "banana", "srawberry", "watermelon"]; let item = arr.splice(0, 1);
console.log(item); // ["apple"]
console.log(arr); // ["orange", "banana", "srawberry", "watermelon"] item = arr.splice(1, 0, "1", "2", "3");
console.log(item); // [];
console.log(arr); // ["orange", "1", "2", "3", "banana", "srawberry", "watermelon"] item = arr.splice(1, 3, "苹果", "香蕉");
console.log(item); // ["1", "2", "3"]
console.log(arr); // ["orange", "苹果", "香蕉", "banana", "srawberry", "watermelon"]
splice()
五、位置方法
indexOf() 和 lastIndexOf(),这两个方法都接受两个参数:要查找的项和(可选的)查找其实位置的索引。
这两个方法的返回值是查找的项在数组中的位置,若没有则返回-1。注意在第一个参数比较数组的每一项时,是采用的全等操作符。
let arr = ["apple", "orange", "100", 2, 3]; let index = arr.indexOf(100);
console.log(index); // -1
index = arr.indexOf("orange");
console.log(index); //
indexOf
六、迭代方法
以下这5个迭代方法都可以传入两个参数:要在每一项上运行的函数和(可选的)运行该函数的作用域对象——影响this的值。在每一项上运行的函数中会接受三个参数:数组项的值、位置、数组对象本身。以下方法都不会改变原来的数组。
6.1 every()
对数组中的每一项都运行指定的函数,如果该函数对每一项都返回 true,则返回 true。
6.2 some()
如果该函数对任意一项返回 true,则返回 true。
6.3 filter()
filter 译为“过滤”,也就是说该方法可以利用指定的函数来确定返回的数组中是否包含某一项,它返回一个数组。
6.4 map()
该方法也是返回一个数组,而这个数组的每一项都是原始数组的每一项经过函数运行后的结果。
6.5 forEach()
将数组的每一项传入函数中,没有返回值,类似于使用 for 循环遍历数组。
let numbers = [1, 2, 3, 4, 15, 16]; let everyResult = numbers.every(function (item, index, array) {
return (item > 3);
});
console.log(everyResult); // false let someResult = numbers.some(function (item, index, array) {
return (item > 3);
});
console.log(someResult); // true function biggerThan_10(item, index, array) {
if (item > 10) {
return item;
}
}
let filterResult = numbers.filter(biggerThan_10);
console.log(filterResult); // [15, 16] function doubleItems(item, index, array) {
return item * 2;
}
let mapResult = numbers.map(doubleItems);
console.log(mapResult); // [2, 4, 6, 8, 30, 32]
迭代方法
七、归并方法
两个归并数组的方式:reduce()、reduceRight(),这两个方法都会迭代数组的所有项,然后返回一个最终值。reduce() 从数组的第一项开始,逐个遍历到最后。reduceRight()相反。
两个方法的都接受两个参数:每一项上调用的函数和(可选的)作为归并的初始值。 每一项上调用的函数有四个参数:前一个值、当前值、索引、数组对象。
let numbers = [1, 2, 3, 4]; let result = numbers.reduce(function(pre, cur, index, array){
console.log("pre: " + pre + ", cur: " + cur + ", index: " + index);
return pre + cur;
})
console.log(result); // // 每次归并的输出:
// pre: 1, cur2, index:1
// pre: 3, cur3, index:2
// pre: 6, cur4, index:3 // 传入归并的初始值
let result_2 = numbers.reduce(function(pre, cur, index, array){
console.log("pre: " + pre + ", cur: " + cur + ", index: " + index);
return pre + cur;
}, 1000)
console.log(result_2); // // 每次归并的输出:
// pre: 1000, cur: 1, index: 0
// pre: 1001, cur: 2, index: 1
// pre: 1003, cur: 3, index: 2
// pre: 1006, cur: 4, index: 3
reduce()
以上JavaScript中Array类型的常见方法,通过这些方法能够使我们在实际中更加方便的操作数组。
最近在学习《JavaScript高级程序设计》这本书,以上内容整理自该书第五章,与Array的更多方法可以参考MDN。