啃一啃犀牛书--数组--方法

啃一啃犀牛书–数组–方法

本章主要针对数组的方法进行概述,多以代码为主。

join()

该方法将数组中的所有元素都转化为字符串并连接在一起,返回最后生成的字符串。该方法接受一个参数,该参数为分隔数组的字符串。默认值为’,’。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
var a = ['a','b','c','d'];
a.join(); // => "a,b,c,d"
a.join('-'); // => "a-b-c-d"
//可以生成一条华丽的分割线
var b = new Array(10);
b.join('-'); // => "---------"
//使用场景比较多,比如我们可以使用这个来完成url后的参数追加;
var a = {
name: 'yxy',
age: 27,
sex: 'man'
}
var b = [];
for(var index in a){
b.push(`${index}=${a[index]}`);
}
b.jion('&'); // => "name=yxy&age=27&sex=man"

reverse()

该方法将数组中的元素颠倒顺序,返回逆序的数组。

1
2
3
var a = [1,2,3,4];
a.reverse();
console.log(a) // => [4,3,2,1]

从这儿可以看出来,该方法会改变原来的数组结构。

sort()

该方法将数组中的元素排序并返回排序后的数组。当不带参数调用该方法时,数组元素
以字母表顺序排序(如有必要将临时转化为字符串进行比较)。

1
2
3
4
5
6
7
8
9
10
11
var a = [33,4,1111,222];
var b = a.sort(); // => [1111, 222, 33, 4] 此时按照字母表顺序进行排序,显然此时的结果并不是我们期望的
console.log(a) // => [1111, 222, 33, 4] 原数组被改变。
var c = a.sort(function(a,b){return a - b}); // [4,33,222,1111] 在方法内传入比较函数,进行升序排列。
//到底是升序还是降序根据比较函数的返回值,如果返回a-b,即升序,返回b - a 即降序。
//此处可进行一些扩展,可以在参数a,b上做一些文章。
var a = ['banner','apple','dog','canlender'];
var d = a.sort(function(a,b){
return a.length - b.length;
}); // => ["dog", "apple", "banner", "canlender"]
//我们以元素的长度来进行排序。

concat()

该方法创建并返回一个新数组,它的元素包括调用concat()的原始数组的元素和concat()的每个参数。

1
2
3
4
5
var a = [1,2,3];
var b = a.concat(4,5); // => [1,2,3,4,5]
var c = a.concat([4,5],[6,7]) // => [1,2,3,4,5,6,7]
var d = a.concat(4,[5,[6,7]]) // => [1,2,3,4,5,[6,7]] 该方法不会递归扁平化数组的数组。也不会改变原有的数组。
console.log(a); // => [1,2,3]

此方法与es6的扩展运算符相同,我们也可以使用扩展运算符来完成这样的操作。

1
2
3
var a = [1,2,3];
var b = [4,5];
var c = [...a,...b] // => [1,2,3,4,5]

slice

该方法返回指定数组的一个片段或者子数组。它接受两个参数,分别指定了片段的开始和结束的位置。返回的数组包含第一个参数指定的位置和所有到但不包含第二个参数指定
的位置之间的所有数组元素。如果只指定一个参数,返回的数组将包含从开始位置到数组结尾的所有元素。如果参数中出现负数,它表示相对于数组中最后一个元素的位置。注意
slice()方法不会修改调用的数组。

1
2
3
4
5
6
var a = [1,2,3,4,5];
var b = a.slice(0,3); // => [1,2,3]
var c = a.slice(3); // => [4,5]
//如果你对这儿有疑问,这里的第一个参数,你可以当做a[3],即4。参照规则,包含第一个参数的指定位置。然后又提供一个参数,所以返回[4,5]
var d = a.slice(1,-1) // => [2,3,4]
var d = a.slice(-3,-2) // => [3]

splice()

该方法是在数组中插入或删除元素的通用方法。它会修改调用的数组。它能够从数组中删除元素、插入元素到数组中或者同时完成这两种操作。在插入或者删除之后的
数组元素会根据需求增加或者减小他们的索引值,因此数组的其他部分仍然保持连续,不能因此而成为稀疏数组。该方法参数并无硬性限制,但第一个参数指定了插入或删除的起始位置,第二个参数指定了
应该从数组中删除的个数。如果第二个参数省略,从起点开始到数组的结尾的所有元素都将被删除。它返回一个由删除元素组成的数组,或者如果没有删除元素就返回一个空数组。

1
2
3
4
5
6
7
8
var a = [1,2,3,4,5,6,7,8];
var b = a.splice(4); // => b = [5,6,7,8] a = [1,2,3,4]
var c = a.splice(1,2); // => c = [2,3] a = [1,4]
var d = a.splice(1,1); // => d = [4] a = [1]
//以上为删除操作
var a = [1,2,3,4,5];
var b = a.splice(2,0,'a','b'); // => b = [] a = [1,2,'a','b',3,4,5]; 这里的第一个参数2,实际上可以理解为,在a[2],这个地方留一个空位来进行插入。
var c = a.splice(2,2,[1,2],3); // => c = ['a','b'] a = [1,2,[1,2],3,3,4,5];

push()、 pop()

这两个方法允许将数组当做栈来使用。push()在数组的尾部添加一个或多个元素,并返回数组新的长度。pop()相反,它删除数组的最后一个元素,减少数组的长度并返回它删除的值。注意
两个方法都修改并替换原始数组而非生成一个修改版的新数组。组合使用push()和pop()能够用js数组实现先进后出的栈。

1
2
3
var a = [];
var b = a.push('a'); // => b = 1 a改变之后的数组的长度。 a = ['a'];
var c = a.pop(); // => c = 'a' a = [];

unshift()、shift()

这两个方法的行为跟上面两个方法类似,只是这两个类似于执行了上面两个方法的相反操作。unshift()在数组的头部添加一个或多个元素,并将已存在的元素移动到更高索引的位置
来获得足够的空间,最后返回数组新的长度。shift()删除数组的第一个元素并将其返回,然后把所有随后的元素下移一个位置来填补数组头部的空缺。

1
2
3
4
var a = [];
var b = a.unshift(1); // => b = 1; a = [1];
var c = a.unshift(22); // => c = 2; a = [22,1]
var d = a.shift(); // => d = 22; a = [1];

toString() 、toLocaleString()

toString()将数组每个元素转化为字符串(如有必要将调用元素的toString()方法)并且输出用逗号分隔的字符串列表。注意,输出不包括方括号或其他形式的包裹数组值的分隔符。

1
2
3
var a = [1,2,3];
a.toSring(); // => '1,2,3'
var b = [1,[2,3]]; // => '1,2,3'

toString()方法如果不添加参数,就跟join()方法类似

toLocaleString()是toString()方法的本地化版本。它调用元素的toLocaleString()方法将每个数组元素转化为字符串,并且使用本地化(和自定义实现的)分隔符来将这些
字符串链接起来生成最终的字符串。

forEach()

该方法从头至尾遍历数组,为每个元素调用指定的函数。类似于for循环,但是不太一样的是,该方法如果想像for循环那样提前中断就不是那么容易了,这儿只能使用
try语句来进行中断。如果我们不需要中断,这个也算是比较简洁的一种循环方式。

1
2
3
4
var a = [1,2,3,4,5,6];
var sum = 0;
a.forEach((x) => {sum += x});
console.log(sum) // => 21

map()

该方法将调用的数组的每个元素传递给指定函数,并返回一个数组,它包含该函数的返回值。

1
2
3
4
5
6
7
var a = [1,2,3];
var b = a.map((x) => x*x); // => b = [1,4,9]
//我们也可以用map方法实现上面的sum
var a = [1,2,3,4,5,6];
var sum = 0;
var b = a.map((x) => sum += x); // => sum = 21 b = [1,3,6,10,15,21]
//这里因为使用的箭头函数,这里我们还是相当于有返回值

我们应该期望有返回值,这样我们的b就不会是一个空数组或者里面全是undefined的数组。毕竟那样一个数组对我们来说是没有什么意义的。

filter()

该方法返回的数组元素是调用的数组的一个子集。传递的函数是用来逻辑判定的:该函数返回布尔值。filter()中的函数有三个参数,分别为当前元素,当前元素的索引,以及当前数组。

1
2
var a = [1,2,3,4,5,6,7,8];
var arr1 = a.filter((x) => x%2 === 0);

注意,filter()会跳过稀疏数组中缺少的元素,它的返回数组总是稠密。

every()、some()

这两个方法是数组的逻辑判定:它们对数组元素应用指定的函数函数进行判定,返回布尔值。

every()方法类似于逻辑与’&’,而some方法类似于逻辑或’||’。从字面上也基本上能看的出来。every()方法当且仅当数组中的所有元素都返回true,它才返回true,否则false。
some()方法,只要其中存在一个元素返回true就返回true,如果都为false,则返回false。

1
2
3
4
5
var a = [1,2,3,4,5];
a.every((x) => x < 10); // true a中所有元素都小于10
a.every((x) => x > 4); // false 部分大于4
a.some((x) => x >4); // true 5>4
a.some((x) => x < 0); // false 所有元素都大于0

reduce() 、 reduceRight()

reduce()方法使用指定的函数将数组元素进行组合,生成单个值。reduceRight()方法与reduce()方法类似,不过它指定了数组的索引书序,从右开始即索引从高到低。

1
2
3
4
5
6
7
8
9
10
11
12
13
var a = [1,2,3,4,5,6];
var b = a.reduce(function(x,y){
console.log(x); // => 1,3,6,10,15
console.log(y); // => 2,3,4,5,6
return x+y
}); // => b = 21
//reduce()可接收第二个可选参数,用来指定默认值。
var b = a.reduce(function(x,y){return x+y},0) // => b = 21
var c = a.reduceRight(function(x,y){
console.log(x); // => 6,11,15,18,20,21
console.log(y); // => 5,4,3,2,1
return x+y;
})

reduce()使用的函数与forEach()和map()使用的函数不同。reduce()指定函数的参数,第一个参数是到目前为止的化简操作积累的结果。第二个参数就是当前所操作的数组的
元素。

在空数组上,不带初始值参数调用reduce()将导致类型错误异常。如果调用它的时候只有一个值——数组只有一个元素并且没有指定初始值,或者有一个空数组
并且给定了初始值——reduce()只是简单的返回那个值而不会调用化简函数。

可能这两个方法用起来知道怎么用,但是对于里面参数并不理解,这就需要多练习了,多尝试,然后打印出过程中的值的变化,你就知道到底是什么意思了。

indexOf()和lastIndexOf()

这两个方法搜索整个数组中具有给定值的元素,返回找到的第一个符合元素的索引,如果没有找到则返回-1.indexOf()从头至尾搜索,laseIndexOf()则相反。这两个方法都
接收两个参数,第一个参数是要搜索的值,第二个可选参数是指定索引位置。即从什么地方开始搜索。

1
2
3
var a = [1,2,3,2,1];
var b = a.indexOf(1); // => 0
var c = a.lastIndexOf(1); // => 4

这里需要注意的是,这两个方法只是搜索顺序的不同,如果只有一个符合条件的搜索元素,不管使用这两个中的哪个方法,返回的都是一样的。

下面是关于es6数组新增的一些方法或者与之相关的操作。可以查看原文ECMAScript 6 入门–阮一峰

扩展运算符

这个在上面已经提到了,使用方法是”…”。这个是es6中提供的运算符。它可以将一个数组转为用逗号分隔的参数的序列。

1
2
var a = [1,2,3];
console.log(...a); // => 1 2 3

这里不再赘述过多的使用,如还未了解或者是想了解,请移步上面的链接。

Array.from()

这个方法用于将两类对象转为真正的数组:类数组对象,可遍历的对象

1
2
3
4
5
6
7
let arrayLike = {
'0': 'a',
'1': 'b',
'2': 'c',
length: 3
}
var b = Array.form(arrayLike) // => ['a','b','c']

Array.of()

该方法用于将一组值转换为数组。

1
Array.of(3,11,8);           // => [3,11,8]

该方法为了弥补new Array()构造函数的不足,因为这个参数不同,结果也不同。

copyWithin()

在当前数组内部,将制定位置的成员复制到其他位置(会覆盖原有成员),然后返回当前数组。
接受三个参数:

  • target(必需):从该位置开始替换数据
  • start(可选):从该位置开始读取数据
  • end(可选):从该位置停止读取数据
1
[1,2,3,4,5].copyWithin(0,3);            // => [4,5,3,4,5]

find()、findIndex()

find()用于找出第一个符合条件的数组成员。findIndex()方法找出第一个符合条件的数组成员的位置(也就是索引,下标)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
const a = [
{
id: 1,
name: '111'
},
{
id: 2,
name: '222'
},
{
id: 3,
name: '333'
},
{
id: 4,
name: '444'
},
];
//常用的一个,我们想根据某一个标识来查到对应的元素
var b = a.find((x) => x.id===2); // => b:{id:2,name:'222'}

fill()

该方法使用给定值,填充一个数组。

1
2
[1,2,3].fill(7);            // => [7,7,7]
new Array(3).fill(7); // => [7,7,7]

entries()、keys()、values()

跟对象的keys方法类似,这三个方法也是用来遍历数组的,他们都返回一个遍历器对象。

1
2
3
4
5
6
7
8
9
10
11
12
13
let a = ['a','b','c'];
let entries = a.entries();
console.log(entries.next().value); // => [0,'a']
console.log(entries.next().value); // => [1,'b']
console.log(entries.next().value); // => [2,'c']
let keys = a.keys();
console.log(keys.next().value); // => 0
console.log(keys.next().value); // => 1
console.log(keys.next().value); // => 2
let values = a.values();
console.log(values.next().value); // => 'a'
console.log(values.next().value); // => 'b'
console.log(values.next().value); // => 'c'

includes()

该方法返回一个布尔值,表示数组是否包含给定的值。

1
2
var a = [1,2,3];
console.log(a.includes(1)); //true

至此为止,数组的一些方法算是简单的介绍了一遍。里面也发现不少自己的问题,比如push返回的是一个什么?可能真的是平时的盲点。