call、apply、bind方法的实现

先分析下3个方法的作用

改变this的指向。

传入参数。

call apply返回函数结果, bind 返回新函数

一、call方法的实现

改变this指向

首先我们知道,对象上的方法,在调用时,this是指向对象的。

call、apply、bind方法的实现

知道了这一点我们就可以实现改变this的指向

call、apply、bind方法的实现

测试

call、apply、bind方法的实现

现在,改变this的值,实现了

最简单实现es6

call、apply、bind方法的实现

二、apply方法的实现

其实apply和call差不多,没什么大区别

利用已经写好的myCall来实现

call、apply、bind方法的实现

不用myCall

call、apply、bind方法的实现

测试

call、apply、bind方法的实现

效果没区别

三、bind方法的实现(利用call方法实现)

首先我们可以通过给目标函数指定作用域来简单实现bind()方法:

call、apply、bind方法的实现

考虑到函数柯里化的情况,我们可以构建一个更加健壮的bind():

call、apply、bind方法的实现

这次的bind()方法可以绑定对象,也支持在绑定的时候传参。

继续,Javascript的函数还可以作为构造函数,那么绑定后的函数用这种方式调用时,情况就比较微妙了,需要涉及到原型链的传递:

call、apply、bind方法的实现

这是《JavaScript Web Application》一书中对bind()的实现:通过设置一个中转构造函数F,使绑定后的函数与调用bind()的函数处于同一原型链上,用new操作符调用绑定后的函数,返回的对象也能正常使用instanceof,因此这是最严谨的bind()实现。

对于为了在浏览器中能支持bind()函数,只需要对上述函数稍微修改即可:

call、apply、bind方法的实现
call、apply、bind方法的实现

四、模拟代码

模拟call

call、apply、bind方法的实现

模拟apply

call、apply、bind方法的实现

模拟bind

call、apply、bind方法的实现