听说、你会用call、apply和bind?

原创 老姚 随笔 我也来说说系列 3372阅读 2017-05-02 11:19:13 举报

想必各位都知道这三者的用法,主要是解决this指向的问题。
然而本文却要小小颠覆你对这三者的认识。

这三者都是Function.prototype对象里面的方法,因此函数都可以调用。
比如,call的使用:
javascript 代码

再比如,类数组转为数组:
javascript 代码

这是借鸡下蛋的典型用法,没啥问题。
我们要切换视角来看下面的代码:

Array.prototype.slice.call(arguments);
原先我们是这么看的,把Array.prototype.slice当作一个函数,然后call一下。
现在我们要这么看,把Array.prototype.slice.call整体当作一个函数,然后调用一下。
我们试一试,看看会有什么效果:
javascript 代码

很遗憾,浏览器报错,说slice不是一个函数。
但slice明明就是Function.prototype.call嘛。
其实这个问题,跟一般的this丢失问题一样的,比如:
javascript 代码

我们怎么解决this丢失问题呢?使用bind就是其中一个解决方式:
javascript 代码

此时我们解决之前切换视角时,this丢失的问题(注意call是Array.prototype.slice的方法)。
javascript 代码

就问句,神不神奇?
slice是数组的方法,可以被其他类数组(包括数组)借用。同时,数组其他的大部分方法也可以被人家借去玩玩的。
比如,我想发明个push函数,对所有类数组都可以如下使用:

push(likeArray, item1, item2)
怎么做呢?很简单:
javascript 代码

这是本文至此的一个小高潮,但还有一大波僵尸来临。
这一“大波”僵尸是什么呢?
那就是我们要强烈地、十分清楚地、永远不要忘记地认识到call、apply和bind本身也是函数
比如,我发明个call:
javascript 代码

比如,我发明个apply:
javascript 代码

比如,我发明个bind:
javascript 代码

其实以上都是反客为主的写法,
本来是obj.action('xxx'),即action是obj的方法。
最后可以改成action(obj, 'xxx'),即obj变成了方法的参数。

最后要说的是,既然有了bind,那么其他的方法就可以简写为:
[quote]var call = bind(Function.prototype.call, Function.prototype.call);
var apply = bind(Function.prototype.call, Function.prototype.apply);
var slice = bind(Function.prototype.call, Array.prototype.slice);[/quote]
我们以slice为例,做下测试:
javascript 代码

就这样,本文完。

鉴于有的同学对this和类数组也很感兴趣,欢迎拓展阅读:
1.《听说,你会this?》
2.《Array为人嫁衣篇》

声明:老姚五一期间没事搜了一下自己的文章,发现有些文章确实被转载了,心里挺开心的。
最后还是要提醒一下,我的所有文章都可以转载的,不必联系我,不过,最好还是贴上声明和链接,比如
作者:老姚
原文://notes/17398/d1c46fcfd6a13e08c91e4448313ce760.html

看到此处,我们该想到,陆游诗人对前端界做出的最大贡献:
纸上得来终觉浅,绝知此事要躬行。

评论 ( 12 )
最新评论
九儿 2017-05-12 09:57:47 12F

一脸懵

aaawhz 2017-05-10 17:05:09 11F

看样子 js 不够严谨

老姚 9F 2017-05-04 16:12:20 10F

实在不行的话,把代码敲一遍就应该懂了。

千本桜 2017-05-04 16:05:46 9F

迷迷糊糊的

我的小苹果 2017-05-04 09:54:52 8F

再来赞一次

我的小苹果 6F 2017-05-03 11:03:47 7F

哈哈哈 姚大太赞

老姚 5F 2017-05-03 11:00:14 6F

这是个黄笑话。。

我的小苹果 2017-05-03 10:50:30 5F

姚大 太

老姚 2F 2017-05-03 10:34:52 4F

thank you!

老姚 1F 2017-05-03 10:34:26 3F

谢谢一如既往地支持

A893111522 2017-05-02 14:23:50 2F

姚大神的干货就是多。

Mr豆花 2017-05-02 12:48:47 1F

先赞了再看,哈哈。