0
点赞
收藏
分享

微信扫一扫

带你一起实现call函数

昨天搞完this指向后,我们顺藤摸瓜来,一起来实现个call方法吧。call、apply、bind中之所以选择call,首先,它简单些。其次,bind的实现需要借助call、apply。最后,就是我个人最常用call。那就让我们开始吧。

call回顾

具体实现前,我们需要回顾一下call的使用方法。相信只有真正掌握了怎么用的人,才更容易把它实现出来。

语法上,call函数接收可供选择的this值,以及不计数量的参数列表。例如:.call(thisArg, arg1, arg2, ...)。又或者,.call(undefined, arg1, arg2, ...)。

功能上,call提供新的this值给当前被调用的函数或者方法。当然,call为新this提供的函数、方法的来源可以是其他对象的函数方法。

使用上,处理修改this指向,它还可以实现继承。比如当你写一个函数,然后让另外一个新的函数去继承它。这样就不用在新函数中写重复代码了。

实现思路

实现前,需要实现的关键问题如下:

  1. 了解call从哪里来?要写在哪里?
  2. 如何修改this指向?
  3. 如何传递参数?
  4. 传入undefined情况怎么解决?

解决思路如下(注:与问题条目一一对应):

  1. javaScript函数都是Function构造函数的实例,所以yourfunction.call(),中的call一定来自于Function.prototype,因此我们只需要将自己要写的myCall挂载到Function原型上即可。
  2. 这里我们需要给目标对象创建一个新的属性,来承载被调用函数的引用地址。然后借用this的隐式绑定,就讲函数挂在到了新对象上。(不懂得小伙伴,看下面具体实现部分就懂了哈)
  3. arguments是一个函数内,对应传递给函数的参数的类数组对象。我们将它直接解构给待执行函数即可。
  4. 我们这里直接当做非严格模式即可,当this为空时,赋值称为window。

实现

有了上面思路梳理,感觉蛮清晰的,所以没加注释。有疑问的小伙伴,欢迎在下方评论。

let name = '今晚打老虎';

function yourFunction(x, y) {
    console.log(this.name, x + y);
}

const YaoShen =  {
    name: 'YaoShen'
}

Function.prototype.myCall = function(obj, ...arg) {
    obj.temFunc = this;
    const result = obj.temFunc(...arg); //这里感兴趣的同学 可以考虑下兼容性
    delete obj.temFunc;
    return result;
}

yourFunction.myCall(YaoShen, 1, 2)

结束语

每天从头到尾,写一篇更文后。都收获了满满的成就感,也对老知识有了新认识。因为要拿出来讲,所以在语言上也有了进步。希望自己能坚持下去。感觉大家的一路同行,我们顶峰相见。

等苦尽甘来的那一天,山河星月都做贺礼。

举报

相关推荐

0 条评论