本文参考:《JS高级程序设计》(红宝书)、
JS数组的独特性
JS中Array
类型属于引用类型,是除了Object
之外最常用的类型。
JS的数组与其他语言的数组有着相当大的区别,它十分灵活,在JS中:
- 数组的每一项都可以是任何类型的数据 (也就是数组各项的类型可以不同)。
- 数组的大小可以动态调整,可随数组的添加自动增长。
创建数组的两种基本方式
- 构造函数方式:可以省略new,可传递数值代表项数,或者传递其他类型代表数组内容。
- 数组字面量表示法:数组字面量由一对包含数组向的方括号表示,多个数组项之间以逗号隔开。
下面是两种方法的实例
// 1、构造函数方式
var colors = new Array(); // new 可省略
// 传递数值代表项数。
var colors = new Array(20); // 创建一个包含20项的数组
// 传递其他类型代表数组内容
var colors = new Array("red", "blue", "green");
复制代码
// 2、数组字面量表示法
var names = []; // 空数组
var colors = ["red", "blue", "green"]; // 包含三项
alert(colors[0]); // red,显示第一项
colors[1] = "Nike"; // 修改第二项
colors[3] = "add"; // 增加数组的第四项
alert(colors.length); // 4
复制代码
length
属性的妙用
Array.length
= 数组的长度length
可用来移除或增加数组的项,被移除或新增项的值为undefined
Array[Array.length]
可以方便的在数组末尾添加项
// 移除
var colors = ["red", "blue", "green"]; // 原本长度为3
colors.length = 2; // 设置长度为2,则移除最后一项
alert(colors[2]); // undefined
// 新增
colors.length = 4; // 设置长度为4
alert(colors[3]); // undefined
// 在数组末尾新增一项
colors[colors.length] = "black";
// 重新改变数组长度
colors[99] = "white";
alert(colors.length); // 100
// 中间位置都是undefined
复制代码
迭代数组的五种方法
数组有5个迭代方法,作用如下:
every()
:函数对每项都返回true,就返回truefilter()
:返回该函数会返回true的项组成的数组forEach()
:只对数组中的每一项运行给定函数,无返回值(即返回undefined)。本质与for循环迭代数组一样map()
:返回每次函数调用的结果组成的数组some()
:函数对任一项返回true,就返回true
每个方法都接收2个参数:
- 要在每项上运行的函数。该函数接收3个参数:
- 数组项的值
- (可选)该项在数组中的位置(索引)
- (可选)数组对象本身
- (可选)运行改函数的作用域对象--影响
this
的值
下面分类进行详细描述。
遍历的两种方法
1. forEach()
:对数组的每个元素执行一次提供的函数,无返回值(即返回undefined)。本质与for循环迭代数组一样。
语法:arr.forEach(callback[, thisArg]);
var numbers = [1,2,3,4,5,4,3,2,1];
numbers.forEach(function(item, index, array) {
console.log(item);
numbers[index]++; // 执行后numbers数组改变,每项增加1
}); // 1 2 3 4 5 4 3 2 1
复制代码
注意forEach()
没有生成新数组,可以改变原有数组。
2. map()
:创建一个新数组,其结果是该数组中的每个元素都调用一个提供的函数后返回的结果(返回每次函数调用的结果组成的数组)。
var numbers = [1,2,3,4,5,4,3,2,1];
var mapResult = numbers.map(function(item, index, array) {
return item * 2;
});
alert(mapResult); // [2,4,6,8,10,8,6,4,2]
复制代码
注意map()
生成新数组,不会改变原数组。
数组判断(断言)的三种方法
1. every()
:测试数组的所有元素是否都通过了指定函数的测试。全通过则返回true
,只要有一项不通过就返回false
。
var numbers = [1,2,3,4,5,4,3,2,1];
var everyResult = numbers.every(function(item,index,array){
return (item > 2);
});
alert(everyResult); // false
复制代码
注意every()
不会改变原数组。
2. some()
:测试是否至少有一个元素通过由提供的函数实现的测试。是返回true
,否则返回false
。
var numbers = [1,2,3,4,5,4,3,2,1];
var someResult = numbers.some(function (item,index,array) {
return (item > 2);·
});
alert(someResult); // true
复制代码
注意some()
不会改变原数组。
3. filter()
:创建一个新数组, 其包含通过所提供函数实现的测试的所有元素。 返回值为一个新的通过测试的元素的集合的数组,如果没有通过测试则返回空数组。
var numbers = [1,2,3,4,5,4,3,2,1];
var filterResult = numbers.filter(function(item,index,array){
return (item > 2);
});
alert(filterResult); // [3,4,5,4,3]
复制代码
注意filter()
不会改变原数组,它返回过滤后的新数组。
查找的两种方法
ES5为数组实例添加了两个位置方法indexOf()
和 lastIndexOf()
。
1. indexOf()
方法返回在数组中可以找到一个给定元素的第一个索引,如果不存在,则返回-1。
2. lastIndexOf()
方法返回指定元素(也即有效的 JavaScript 值或变量)在数组中的最后一个的索引,如果不存在则返回 -1。从数组的后面向前查找,从 fromIndex 处开始。
这两个方法都接收两个参数:
- 要查找的项(searchElement)
- (可选)表示查找起点位置的索引(fromIndex)
这两个方法的查找方向:
indexOf()
方法:从开头向后查找lastIndexOf()
:从末尾向前查找
这两个方法都返回:
- 要查找的项所在数组中的位置,没找到的情况下返回
-1
注意要求查找的项必须严格相等(即 ===
)
下面是一个实例,比较两种方法
var numbers = [1,2,3,4,5,4,3,2,1];
alert(numbers.indexOf(4)); // 3。注意4是value,3是index
alert(numbers.lastIndexOf(4)); // 5
alert(numbers.indexOf(4, 4)); // 5
alert(numbers.lastIndexOf(4,4)); // 3。因为是从索引4向前查找,所以第一个找到的是索引3
复制代码
模拟队列的四种方法
队列特点:先进先出,队列在列表末端添加,前端移除。
正向模拟队列的两种方法
1. push()
:就是栈方法,数组末端添加n项。
将一个或多个元素添加到数组的末尾,并返回该数组的新长度。
此方法更改数组的长度。
var colors = new Array();
var count = colors.push("red", "green");
alert(count); // 2
复制代码
2. shift()
:数组前端移除一项,长度-1,返回移除的项(即原数组第一项)
从数组中删除第一个元素,并返回该元素的值。
此方法更改数组的长度。
var colors = new Array();
var count = colors.push("red", "green");
alert(colors.shift()); // "red"
复制代码
反向模拟队列的两种方法
1. pop()
,数组末端移除一项,返回移除项
从数组中删除最后一个元素,并返回该元素的值。
此方法更改数组的长度。
var plants = ['broccoli', 'cauliflower', 'cabbage', 'kale', 'tomato'];
console.log(plants.pop());
// "tomato"
复制代码
2. unshift()
,数组前端添加任意项,返回新数组长度
将一个或多个元素添加到数组的开头,并返回该数组的新长度。
此方法更改数组的长度。
var array1 = [1, 2, 3];
console.log(array1.unshift(4, 5));
// expected output: 5
复制代码
操作数组的三种方法
1. concat()
:合并两个或多个数组。相当于+
。
创建当前数组的副本,将接收到的参数添加到副本末尾,返回副本。
此方法不会更改现有数组,而是返回一个新数组。
var array1 = ['a', 'b', 'c'];
var array2 = ['d', 'e', 'f'];
console.log(array1.concat(array2));
// expected output: Array ["a", "b", "c", "d", "e", "f"]
复制代码
2. slice()
:剥离复本,基于当前数组中的几项创建一个新数组。
返回一个新的数组,包含从 start 到 end (不包括该元素)的 arrayObject 中的元素。
原型:arrayObject.slice(start,end)
,start必选,end可选。start若是负值,则从尾部选取。
此方法不会更改现有数组,而是返回一个新数组。
var colors = ["red","green","blue","yellow","purple"];
var colors2 = colors.slice(1);
var colors3 = colors.slice(1,4);
alert(colors2); // green,blue,yellow,purple
alert(colors3); // green,blue,yellow
复制代码
3. splice()
:向数组中添加或从数组中删除项目,然后以数组形式返回被修改的内容。
语法:array.splice(start[, deleteCount[, item1[, item2[, ...]]]])
-
start
必需。整数,指定修改的开始位置(从0计数)。使用负数可从数组结尾处规定位置。 -
deleteCount
可选。整数,表示要移除的数组元素的个数。如果 deleteCount 是 0或者负数,则不移除元素。这种情况下,至少应添加一个新元素。
如果 deleteCount 大于start 之后的元素的总数,则从 start 后面的元素都将被删除(含第 start 位)。
如果deleteCount被省略,则其相当于(arr.length - start)。
-
item1, item2, ...
可选。要添加进数组的元素,从start
位置开始。如果不指定,则splice()
将只删除数组元素。
转换数组的四种方法
所有对象都具有的toLocaleString()
、toString()
、 valueOf()
方法和改变分隔符的 join()
方法。
1. toLocaleString()
:返回一个字符串表示数组中的元素。
2. toString()
:返回逗号分隔的字符串形式拼接
返回一个字符串,表示指定的数组及其元素。
var array1 = [1, 2, 'a', '1a'];
console.log(array1.toString());
// expected output: "1,2,a,1a"
复制代码
3. valueOf()
:返回数组本身
返回一个新的 Array Iterator 对象,该对象包含数组每个索引的值。
const array1 = ['a', 'b', 'c'];
const iterator = array1.values();
for (const value of iterator) {
console.log(value); // expected output: "a" "b" "c"
}
复制代码
4. join()
:改变分隔符,返回字符串
方法将一个数组(或一个类数组对象)的所有元素连接成一个字符串并返回这个字符串。如果数组只有一个项目,那么将返回该项目而不使用分隔符。
var elements = ['Fire', 'Wind', 'Rain'];
console.log(elements.join());
// expected output: "Fire,Wind,Rain"
console.log(elements.join(''));
// expected output: "FireWindRain"
console.log(elements.join('-'));
// expected output: "Fire-Wind-Rain"
复制代码
重排序方法的两种方法
1.sort()
:对数组元素进行排序,直接在原数组上进行排序,不会新建数组。
语法: arr.sort([compareFunction])
compareFunction
用来指定按某种顺序进行排列的函数。如果省略,元素按照转换为的字符串的各个字符的Unicode位点进行排序。
如果指明了 compareFunction
,那么数组会按照调用该函数的返回值排序。即 a 和 b 是两个将要被比较的元素:
- 如果
compareFunction(a, b)
小于 0 ,那么 a 会被排列到 b 之前; - 如果
compareFunction(a, b)
等于 0 , a 和 b 的相对位置不变。备注: ECMAScript 标准并不保证这一行为,而且也不是所有浏览器都会遵守(例如 Mozilla 在 2003 年之前的版本); - 如果
compareFunction(a, b)
大于 0 , b 会被排列到 a 之前。 compareFunction(a, b) 必须总是对相同的输入返回相同的比较结果,否则排序的结果将是不确定的。
function compare(a, b) {
if (a < b ) { // 按某种排序标准进行比较, a 小于 b
return -1;
}
if (a > b ) {
return 1;
}
// a must be equal to b
return 0;
}
复制代码
2. Array.reverse()
将数组中元素的位置颠倒,并返回该数组。该方法会改变原数组。
var array1 = ['one', 'two', 'three'];
console.log('array1: ', array1);
// expected output: Array ['one', 'two', 'three']
复制代码
数组计算的两种方法
reduce()
和reduceRight()
方法,一个从头往后遍历,一个从后往前遍历
这两个方法都接收两个参数:
-
在每一项上调用的函数。函数有4个参数:前一个值,当前值,项的索引,数组对象。
该函数返回的任何值都会作为第一个参数自动传给下一项。
-
作为归并基础的初始值(可选)
1.reduce()
方法对数组中的每个元素执行一个由您提供的 reducer
函数 (升序执行),将其结果汇总为单个返回值。
var values = [1,2,3,4,5];
var sum = values.reduce(function(prev,cur,index,array){
//第一次prev是1,cur是2;第二次prev是1+2=3,cur是3
return prev+cur;
});
alert(sum);//15
复制代码
2. reduceRight()
方法接受一个函数作为累加器(accumulator)和数组的每个值(从右到左)将其减少为单个值。
var values = [1,2,3,4,5];
var sum = values.reduceRight(function(prev,cur,index,array){
// 第一次prev是5,cur是4;第二次prev是5+4=9,cur是3
return prev+cur;
});
alert(sum); // 15
复制代码