【javascript】扁平化二维数组中apply的妙用

背景

  • 昨天群里面有人发了一道二维数组扁平使用的方法,我感觉特别有意思,给各位看看。
var arr=[[1,2,3],[4,5,6],[7,8,9]]
var arr2=Function.prototype.apply.call(Array.prototype.concat,[],arr);
console.log(arr2);

输出:

[ 1, 2, 3, 4, 5, 6, 7, 8, 9 ]

于是我就研究了一下到底是怎么个回事。


首先说一下apply和call

  • apply和call的区别主要就在第二个参数上,apply第二个参数是数组,call后面可以跟一堆东西当参数。
  • 我在百度时候发现有些博客里说Function.prototype.apply.call等于Function.prototype.call.call,在这题里面换一下看看就发现明显不对,结果不一样。我后来发现实际上就是写博客的这人不知道apply这种特殊性质。如果提供给apply的参数是个二维数组,且二维数组里的一维没有除了数组以外的元素,那么apply就可以直接把二维数组里的东西取出来,至于取出来东西是数组还是别的东西,apply不会继续往下取了。
  • 所以从上一段描述来看,apply扁平的二维数组很有限,而且算是特例中的特例了。
  • 猜想apply的特性是因为页面中去除标签很容易导致提取出二维数组的存在而做的适配。

再解释一下运行过程

  • 这个Function.prototype.apply.call(Array.prototype.concat,[],arr)其实就可以看成function-apply.call(function-concat,[],arr),也就是等于function-concat.function-apply([],arr)function-concat 实际是个array的方法,那么按照包装类继承原则,可以把function-concat 替换为[].concat,再看apply,原题目是在Function.prototype下拿的apply,同理根据包装类继承原则,concat实际上是个函数,函数的__proto__也就是老爸,就是Function,那么concat继承了老爸的特性它必然有apply这个方法。最后这个就可以看成[].concat.apply([],arr)。是不是比Function.prototype.apply.call(Array.prototype.concat,[],arr)简短多了,一个明明很简单就能写出来效果一样的东西还非要舍近求远一下。
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

业火之理

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值