apply
call
bind
这三个函数可以改变 this
的绑定,语法上有略微差别,可以看我很早之前的一篇文章做过简单的介绍 浅谈JavaScript中的apply、call、bind。
this 优先级
new
关键字。函数被new
调用,this
指向由new
新构建出来的这个对象- 函数通过
apply call bind
调用,this
指向绑定的对象 - 函数被调用时,
this
指向调用的对象 - 默认。非严格模式情况下,this指向window, 严格模式下,this指向undefined。
总结一下优先级new
关键字 > apply call bind
> 函数调用 > 默认
实现
我们既然要重写 apply
,那前两个优先级是用不了的。我们使用第三个优先级——函数调用——改变 this
的指向。
先看下代码
1 | Function.prototype.myApply = function (context, args) { |
上面的代码忽略一些边界情况,实现了简易版的 apply
。
看下使用的效果
1 | const person = { |
首先我们创建了一个 Symbol
对象作为 context
的 key
,并把 this
赋值给他。此时的 this
值为 getName
,因为是 getName
调用了 myApply
,所以 this
指向调用者。
当我们以 context[key](...args)
这种方式调用 getName
时,this
指向了 context
,因为是 context
调用了 getName
方法。借此完成了 this
值得转换。
call
和 bind
同理
call
1 | Function.prototype.myCall = function (context, ...args) { |
bind
的实现可以使用我们写的 call
函数。需要注意的是 bind
可以传参,新生成的函数也可以传参。
1 | Function.prototype.myBind = function (context, ...args) { |