Q17.你真的理解apply吗?

      人们常说,要学好js,多尝试自己实现一些polyfill。但是呢,一般人会去先使用它,然后才去手撕它。我们今天并不想说手撕的问题,因为我觉得我还没有使用好它,你呢?不妨看看下面怎么说的。

1.我们都知道apply可以改变this指向的问题

2.我们还知道apply接受的第二个参数是一个数组,是一个数组。

3.甚至知道apply和call都是改变this指向的,而区别就是call的第二个、第三个等参数是序列。

但是呢?

有一天,问题出现了,觉得apply没什么好难得,会用皆大欢喜,但是你真的会用吗?

看看一个例子:

function bar(x,y){
	console.log(x,y); //x=[1, 2, 3],y=undefined
	console.log(arguments);
}
bar([1,2,3]);

arguments如下:

是不是很正常。

再看看一个例子:

function bar(x,y){
	console.log(x,y); // x=1 ,y=2
	console.log(arguments);
}
bar.apply(window,[1,2,3]);

arguments如下:

咦,怎么arguments的length变为3. 怎么传过去的数组展开了。

是怎么回事呢?bug?不对?

但是,可爱的小伙伴,还是知道问题所在。那试问一下,你真的理解apply的第二个参数是一个数组吗? 

听我说说看:理解apply的第二个参数是一个数组,要知道数组的作用,收集所用要传给被调函数于一个容器(数组),传过去方便。但是不能理解为一个参数。正所谓在被调函数的参数这边依然是展开的,而不是一个数组。所以arguments的length是3不是1.

不妨我们再看看call吧:

function bar(x,y){
	console.log(x,y); //x=[1,2,3] ,y=undefined
	console.log(arguments);
}
bar.call(window,[1,2,3]);

同样还是再看看arguments:

和apply不一样吧,能是这样的结果,就是因为call的第二、第三等参数是序列。你既然传了一项,那么在那边被调参数那边也就一项,即使你是数组。

总结一个小技巧:如果要将arguments传给另一个函数,那么选择apply最好。被调函数里面的arguments[0],arguments[1],arguments[2]等同样可以获取到。如同call传过来的一样,只不过call的实参要传一个arguments展开写不方便。

还有一个小技巧:实现两个数组的拼接。

var arr=[1,2];
[].push.apply(arr,[3,4,5])  等价于  [].push.call(arr,...[3,4,5])

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值