今天偶然间看到了数组扁平化的一个方法,很简单只有一行代码,对于初学者小白来说很适合使用,但是有局限性,下面我们来看看吧。
let aa=[[12,21],[1,2,3],[2,3,4]];
function turn (arr){
return [].concat.apply([],arr);
}
console.log(turn(aa));
输出的结果呢当然就是
下面躁动不安的我开始胡思乱想为什么这样一行语句就可以把数组拆开呢,apply在这里扮演着什么样的角色,不用它行不行,为什么apply([],arr)要这样写,[] 又代表了什么,用null可不可以 this,Array,String,又会怎样。
apply和call还有bind都是用来改变this指向的 他们的第一个参数就是用来改变this的,之后的参数才是用来传参的,那么问题就来了,这里不用apply用call可以不?答案是不行!因为apply的特殊性,它是apply(this,[arr1,arrr2,arr3])这样来传参的,它的第二个参数就是以一个数组形式进行传参,所以很明显很符合我们之前的题目设定,所以[[12,21],[1,2,3],[2,3,4]]=>[arr1,arrr2,arr3] ,arr1=>[12,21]; arr2=>[1,2,3]; arr3=>[2,3,4]; apply会分别依次把参数传过去,之后运用concat来把这些单独的数组相连接变成了一个数组。
好,现在明白了apply的意义,我们来看一下为什么要写apply([],arr),[] 的作用是什么。首先我们不写[],我们写一下this,看看输出了什么
[].concat.apply(this,arr);
哎?这是什么情况,第一个值怎么是window?长度为什么是9?那个window是那里来的?再来看看Array
[].concat.apply(Array,arr);
这次怎么是Array了 不行再看看String
[].concat.apply(String,arr);
发现规律了吧,写谁 谁就是第一个,为什么呢?由于apply是改变this指向的 所以(我拿this第一个window举例)第一个参数代表的就是本体,其余的所有人在我之后存储,因为window本身是有内容的 根据concat连接所以会把剩下的都加在window的后面,也就是说:window本身不是多出来的 人家本身就在自己家里没动(第一个人下标为0),是后来这些小屁孩占用了自己的老巢成为了这个家里的第二个人、第三个人、第四个人...为什么写[]就不会出现这个情况呢,就是因为本来这个家里就没人没有第一个人,所以后来的人就成为了第一个人、第二个人....
如果这样说你还没有懂的话,那么再来个更简单的例子:
var a=[1,2,3],b=[4,5,6];
[].push.apply(a,b);
console.log(a); //1,2,3,4,5,6
console.log(b); //4,5,6