JS手写实现call、apply、bind

目录

写在前面

call手写实现

apply手写实现

bind手写实现


写在前面

今天的主题是手写实现某些常见的js函数。在JavaScript中,我们知道改变一个函数的this指向,一般来说有这样三个函数可以帮助我们做到这样的效果,分别是call、apply、bind。但是三个函数又有所区别,具体的区别我就不详述了,大家可以去call、apply、bind详细介绍看看详细的介绍。

call手写实现

    var age = 16;
    var gender = 'female';

    var obj = {
      age: 11,
      gender: 'male'
    }

    function Test(a, b) {
      console.log(this.age);
      console.log(this.gender);
      comsole.log(a);
      comsole.log(b);
    }

我们先来看看js的原生call函数的效果,请看下面代码:

    Test(3, 5);
    Test.call(obj, 22, 33);

其输出结果如下:

ok,下面我们来自己首先代码实现我们自己的call函数,show you the code:

    Function.prototype.myCall = function (obj, ...args) {
      obj.fn = this;
      let res = obj.fn(...args);
      delete obj.fn;
      return res;
    }

同样的,我们来调用我们的myCall函数:

    Test.myCall(obj, 22, 33);

输出如下:

很显然,我们已经实现了call函数的功能,下面我们简单的分析一下实现的原理及思路:首先myCall函数是挂载在Function构造函数的原型上的,这没什么好解释的,大家都懂;其次,我们都知道调用myCall函数的第一个参数为this的指向,所以第一个参数单独写,然后怎样让函数的调用时this指向这个参数呢?这时我们可以利用对象的方法调用时,其方法的his指向此对象,所以我们把原函数当作一个方法挂载在第一个参数obj上,所以我们可以看到 obj.fn = this; 这行代码,此时就实现了改变this的指向,此时最最重要的部分已经被我们解决了,接下来的事情不多说了,水到渠成。

apply手写实现

先来看看apply的调用及调用后的效果:

    Test.apply(obj, [36, 37]);
    // 输出如下:
    11
    "male"
    36
    37

下面开始实现我们自己的apply:

    Function.prototype.myApply = function(obj, args) {
      obj.fn = this;
      let res;
      if (args && args.length) {
        res = obj.fn(...args);
      } else {
        res = obj.fn();
      }
      delete obj.fn;
      return res;
    }

下面调用一下我们自己的myApply函数试试看效果:

    Test.myApply(obj, [55, 56]);
    // 输出如下:
    11
    "male"
    55
    56

可以看到,我们自己手写的myApply函数同样是达到了效果,原理同上就不在此赘述了。

bind手写实现

这里,我们直接手写我们自己的bind函数,就不再赘述原生的bind函数了,直接上code:

    Function.prototype.myBind = function(obj, ...args) {
      obj.fn = this;
      return function() {
        const newArgs = args.concat(...arguments);
        let ret = obj.fn(...newArgs);
        delete obj.fn;
        return ret;
      }
    }

调用我们自己的myBind函数看看效果:

    Test.myBind(obj, 66, 67)();
    Test.myBind(obj, 77)(78);

    // 分别输出如下:
    11
    "male"
    66
    67

    11
    "male"
    77
    78

 

  • 3
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值