一 数组分类
一 可以改变原数组的方法
- push()
- pop()
- shift()
- unshift()
- splice()
- sort()
- reverse()
- flat()
二 不会改变原数组的方法---返回新的数组
- filter()
- concat()
- slice()
- join()
二 函数解释与对比
##push()
首先介绍push()函数,我想大家可能已经对这个方法很了解了。
这个方法是数组的末尾加入一个或者多个元素,并返回新的数组的长度。
举个例子:
var aaa = ["1", "2", "3", "4", "5", "6", "7"];
aaa.push("a");
console.log(aaa)我们定义好一个名为aaa的数组 然后用push方法增加一个元素“a”,我们会发现他返回了数值8,而8刚好是新的数组的长度,我们再次在控制台输出aaa发现数组的末尾添加了一个元素a。

当让我们也可以一次性的添加多个元素,比如aaa.push("a","b","c","d")
##pop()
pop()函数的作用是去掉数组末尾的一个元素,并返回被删除的那个数组元素。当我们对数组aaa执行
aaa.pop();的时候,输出结果以及原数组的情况如下图所示,返回值为被删除的元素。

##shift()
shift()函数的作用是删除掉数组起始位置的元素,并返回被删除的数组元素。同理,执行
aaa.shift()的时候,输出结果以及原数组的情况如下图所示,返回值为被删除的元素。

##unshift()
unshift()函数的作用和push()的用法类似,但是unshift()的作用是在数组的起始位置添加一个或者多个新的元素。返回新的数组长度。依旧以aaa数组为例,当我们执行
aaa.unshift("First");的时候,结果如下,原数组变化情况如下。

当然,我们也可以像push()的用法一样,一次性的插入多个元素
aaa.unshift("123","Second");##splice()
splice()函数的作用相对灵活一些,方法通过删除或替换现有元素或者原地添加新的元素来修改数组。并以数组形式返回被修改的内容。
首先看一下他的语法(大家也可以移步MDN官方文档来查看详解)
array.splice(start[, deleteCount[, item1[, item2[, ...]]]])
start参数:指定修改的开始位置(从0计数)。如果超出了数组的长度,则从数组末尾开始添加内容;如果是负值,则表示从数组末位开始的第几位(从-1计数,这意味着-n是倒数第n个元素并且等价于array.length-n);如果负数的绝对值大于数组的长度,则表示开始位置为第0位。
上面是官方文档里面的说法,可能听起来比较绕,但是大体总结起来就是正常从0开始算,负数从后往前数。
deleteCount参数:可选。
deleteCount 为整数,表示要移除的数组个数。
deleteCount被省略,那么start之后的数组全被删除。
deleteCount为0或者负数,不移除,并且从start位置添加一个新元素。
item1.....参数:可选 要添加的元素。
看到这splice()函数的描述文字最多。而且当你状态不好迷迷糊糊的时候不容易看进去?看进去了是不是不容易记住?没关系,我们练一遍就好了。别信广告,信疗效!
我们随便定义一个数组,暂且叫他。。没错。。还是aaa,然后我们输入以下代码
aaa.splice(1,2);
console.log(aaa);这段代码的意思就是,aaa数组,从0开始数,从1开始删除2个元素。如下图所示,aaa数组共8个元素,从索引为1开始删除2个,返回值为["2","3"]--这就是以数组形式返回被删除的数组--原数组aaa长度变为2。这是对于数组的删除操作。

例子2,没错,继续是aaa数组,我们打开控制台输入以下代码对其操作,看看效果。
aaa.splice(1,0,"child1","child2");
console.log(aaa);这段代码的意思aaa数组从第一位开始删除0个,添加child1和child2元素。
由于是删除0个元素,所以返回结果为一个空数组。这是对数组的添加操作。

例子3,继续对aaa数组进行如下操作
aaa.splice(0,3,"parent1","parent2");这段代码的意思是aaa数组从第0位开始删除3个元素,并添加parent1和parent2两个元素。这就相当于将2个元素进行了替换操作。

基于以上,我们再继续列举几种情况。
aaa.splice(-2,2);将aaa数组从末位第二个开始删除2个。当然,虽然start对应的参数是-2,但这只意味着从末位第几位开始,所有计数都要从前往后数的。。。。。。

aaa.splice(2);将aaa数组从第二位开始以后的全部都删除掉。

好,对于aaa数组的折腾暂时就到这。splice()函数灵活多变,需要活学活用。
##sort()
用原地算法对数组的元素进行排序,并返回数组。默认排序顺序是在将元素转换为字符串,然后比较它们的UTF-16代码单元值序列时构建的。
以上是官方文档的解释,它里面强调了一句话先将元素抓华为字符串,然后再进行比较。这句话啥意思呢?我们先来举个例子。
var array1 = ["1","2","10000","9999","4","3","8","901","10"];
array1.sort();可能我们原来想的结果,亦或者按照数值的从小到大,亦或者按照从大到小。但是,结果总是残酷的。

如上图,经过排序的array1数组变成了["1", "10", "10000", "2", "3", "4", "8", "901", "9999"] 这样的一个数组。虽然与我们现象的不一样,但是冥冥之中貌似也有一种规律可循似的。那我们怎样才能得到我们自己想要的排序呢?我们先看以下sort()的语法:
arr.sort([compareFunction])
compareFunction参数:用来指定按某种顺序进行排列的函数。如果省略,元素按照转换为的字符串的各个字符的Unicode位点进行排序。(后面这句话就解释了冥冥之中的规律就是这个)
他居然可以是一个函数!!!那就好了,那就意味着,我想怎么样让他排序,他就得怎么给我排序!
首先,我想让你按照数值的从大到小进行排列
array1.sort((a,b) => b-a)利用以上代码,array1数组的结果就变成了 ["10000", "9999", "901", "10", "8", "4", "3", "2", "1"]
那要是是从小到大呢????我不会,你自己想--手动苦瓜脸~~~总之你可以根据你自己的需求想怎么排序就怎么排序。
##reverse()
这个方法比较简单,颠倒数组中元素的位置,改变了数组,并返回新数组。就是头变尾,尾变头。
简单来说呢,就是
var a = ["1","2","3"];
console.log(a);
a.reverse();
console.log(a);第一个输出的结果是["1", "2", "3"],第二个输出结果是["3", "2", "1"]。结果显而易见。
官方晚上给出了一个很好的例子,可以延申学习一下。我们首先定义一个类数组bbb它包含三个元素和一个length属性。
var bbb = {0: 1, 1: 2, 2: 3, length: 3}如果我想调转bbb的话,直接使用reverse()是不可以的。需要做一下小操作。
Array.prototype.reverse.call(bbb);这样就可以调换bbb了,调换结果如下:
{0: 3, 1: 2, 2: 1, length: 3}
关于call方法和相关的apply方法网上有很多详细解释,我再这里就不再多说了,大家可以自行百度以下。
##flat()
方法会按照一个可指定的深度递归遍历数组,并将所有元素与遍历到的子数组中的元素合并为一个新数组返回。
如果您没明白上面这段话啥意思,咱们直接上代码。
var arr1 = [1, 2, [3, 4]];
arr1.flat();
// [1, 2, 3, 4]
var arr2 = [1, 2, [3, 4, [5, 6]]];
arr2.flat();
// [1, 2, 3, 4, [5, 6]]
var arr3 = [1, 2, [3, 4, [5, 6]]];
arr3.flat(2);
// [1, 2, 3, 4, 5, 6]
//使用 Infinity,可展开任意深度的嵌套数组
var arr4 = [1, 2, [3, 4, [5, 6, [7, 8, [9, 10]]]]];
arr4.flat(Infinity);
// [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]任你任意深度我都可以给你扁平化,此方法何以灵活的和call和apply搭配使用。
小结
至此我们把可以改变数组4的方法都简单的介绍了一下,他们有的方法可以相互替代,这个就需要具体根据实际情况去使用了。关于他们的返回值需要注意一下,有的是返回新的数组,而有的则是返回数组长度以及被操作的数组元素。
那么这里我们再引申一个问题,假设有这么一种情况
我先定义了一个数组aaa然后我们定义一个数组bbb让他等于aaa,这个时候我们操作aaa数组的话,bbb会跟着变化吗?
var aaa = ["a","b","c"];
var bbb = aaa;
aaa.pop();
console.log(aaa);
console.log(bbb);经过试验我们会发现,其实修改其中任何一个另一个都会跟着变化。这是因为JS中Array是引用类型,也就是说aaa和bbb他们的原始数据存储的地址是一致的,所以修改了数据之后,他们都会跟着变。那么如果我希望修改数据并且不改变原来数组要怎么办呢?这个时候不改变原数组的函数就可以闪亮登场了。
##filter()
filter()是创建了一个新的数组,其包含所提供的函数预测的所有元素。
从上面的意思上看,他会创建一个新的数组,不改变原有的数组。我们可以创建一个函数来再数组中提取中我们需要的元素。知道了这两个信息,我们就可以做一个简单的例子。
var array2 = ["1","2","3","4","5","6","7","8"];
var array3 = array2.filter(item => item >5);
console.log(array2);
console.log(array3);第一个输出结果依旧是原数组没有改变:["1", "2", "3", "4", "5", "6", "7", "8"]
第二个输出结果变成了数组中大于5的元素:["6", "7", "8"]
这样就可以验证了我们以上说的那些信息。
我这里面只是举了一个简单的例子,我们可以自行根据实际情况写一个过滤数据的方法,然后利用这种形式 --某数组.filter(自己写的function)-- 来实现过滤,查找等操作。
##concat()
方法用于合并两个或多个数组。此方法不会更改现有数组,而是返回一个新数组。
根据字面意思我们就可以知道他的用途,直接上代码加深一遍印象!
var num1 = [1, 2, 3],
var num2 = [4, 5, 6],
var num3 = [7, 8, 9];
var nums = num1.concat(num2, num3);
console.log(nums);
// results in [1, 2, 3, 4, 5, 6, 7, 8, 9]##slice()
方法返回一个新的数组对象,这一对象是一个由 begin 和 end 决定的原数组的浅拷贝(包括 begin,不包括end)。原始数组不会被改变。
begin:提取起始处的索引(从 0 开始),从该索引开始提取原数组元素。
end:提取终止处的索引(从 0 开始),在该索引处结束提取原数组元素。
二者结尾可选参数,非必选。
这个方法貌似和splice()很像,但又有很多不同。直接上代码看结果
const animals = ['ant', 'bison', 'camel', 'duck', 'elephant'];
console.log(animals.slice(2));
// expected output: Array ["camel", "duck", "elephant"]
console.log(animals.slice(2, 4));
// expected output: Array ["camel", "duck"]
console.log(animals.slice(1, 5));
// expected output: Array ["bison", "camel", "duck", "elephant"]看到结果大家就应该明白了。而且slice()不改变原数组!
##join()
方法将一个数组的所有元素连接成一个字符串并返回这个字符串。如果数组只有一个项目,那么将返回该项目而不使用分隔符。
join()的语法只有一个参数,这个参数就是我们指定的字符串来作为分隔符。
老规矩,直接撸代码。
const elements = ['Fire', 'Air', 'Water'];
console.log(elements.join());
// expected output: "Fire,Air,Water" 默认分隔符是逗号
console.log(elements.join(''));
// expected output: "FireAirWater"
console.log(elements.join('-'));
// expected output: "Fire-Air-Water"
const element1 = ['Fire'];
console.log(element1.join('-'))
//expected output: "Fire"
const element2 = []
console.log(element2.join('-'))
//expected output: 空字符串三 总结
其实关于JS的数组操作的方法还有很多,这里就不一一列举了。给大家一个传送门,以后可以当作一个工具文档来随时查阅。