call()
、apply()
、bind()
都是用来干嘛的?我们先来看2个例子
-
例1的运行结果:
-
例2的运行结果:
比较一下这两者的
this
的差别,第一个打印里面的this
指向obj
;第二个全局声明的shows()
函数,this
是window
。而call()
、apply()
、bind()
方法就是用来重新定义this
这个对象的!如:
以上返回的结果都是一致的,this
指向了db
对象,只是bind
方法后面多了一个()
,由此也得出结论,bind
返回的是一个函数,你必须重新调用它才会被执行。那这个函数是重新生成的还是原来的函数呢,我们来验证一下,验证如下:
我们看到
bind
返回的是一个函数,当拿这个函数和原来的函数进行比较时,发现返回结果为false
,也就是bind
返回的是一个新的函数,新的函数的this
的指向是我们调用bind
时,传递的是第一个参数的值。
那既然bind
返回的是一个新的函数,那我们是否可以继续修改这个新函数的this
的指向呢,验证代码如下:
我们看到当我们对
bind
返回的函数再次调用修改bind
修改this
的指向时,this
的指向和之前是一样的,也就是我们无法再次修改bind
返回函数的this
的指向,也就是通过调用bind
函数修改this
指向以后,this
的指向无法再次修改,会固定为第一次调用bind
函数传的第一个参数的值。
- 下面我们再测试一下通过
call
、apply
修改this
指向以后,是否还可以再次更改this
的指向
经过验证,说明通过调用
call
、apply
函数修改this
指向以后,this
的指向可以被再次修改,而原因就是call
、apply
是在运行时才修改原函数的this
的指向,
- 我们再对比一下
call
、apply
、bind
传参的情况:
从上面4个结果可以看出:
call
、bind
、apply
这三个函数的第一个参数代表this
的指向对象,第二个参数有差别了:
call
的参数是直接放进去的,第二个,第三个第n个参数都用逗号分割,直接放到后面obj.myFun.call(db,“河南”,“深圳”,…,“string”)。apply
的所有参数都必须放在一个数组里面传进去obj.myFun.apply(“db”,[“河南”,“深圳”,…,“string”])。bind
除了返回是函数以外,它的参数和call
是一样。当然三者的参数不限定是string
类型,允许是各种类型,包括函数,对象等等!
总结如下:
call
、apply
、bind
三个函数都是用来更改函数this
的指向的;call
、apply
函数返回的是对应函数的返回值;bind
函数返回一个新函数,需要再次调用bind
返回的函数才会更改this
的指向;- 通过
call
、apply
更改this
指向以后的对象,还可以再次调用call
、apply
函数更改this
的指向,而通过bind
函数更改this
以后,this
的指向固定,再次调用bind
函数,无法更改this
的指向; - 三个函数传参的方式有所区别,第一个参数都是代表
this
的指向,call
、bind
的第二个,第三个,第n个参数都是用逗号分割,直接放到call
或者bind
方法里面;apply
的第二个参数是一个数组,所有需要的参数需要放到一个数组里面再作为apply
的第二个参数传进去