美文网首页
前端重学之路——bind、call、apply

前端重学之路——bind、call、apply

作者: 黑莓小宝闪电朵朵 | 来源:发表于2019-03-04 19:56 被阅读0次

    今天来重温一下更改this指向的三种方法bind, call, apply。

    突然面试被问到了,bind和call的区别?直接一脸懵逼,后来查了一下:bind改变this指向之后回返回一个函数,不会立即执行,需要手动触发一下。

    call、apply、bind正常用法


    let user = {
      birthday: '2/25'
    }
    var test = getData.bind(user);
    function getData(name, age) {
      console.log('name', name);
      console.log('age', age);
      console.log('this.birthday', this.birthday);
    }
    // call和apply只是传入方式不同,call是列表,apply是数组
    getData.call(user, 'tian', '22');
    getData.apply(user, ['tian', '22']);
    test(); // this.birthday 2/25
    

    call、apply、bind模拟方法


    call实现方法

    // 原理是我们可以通过给user创建个gatData方法,然后执行完后再删除来模拟更改this指向的操作。
    Function.prototype.call = function (context) {
      // 获得this指向的对象
      var cxt = context || window;
      // 改变传入对象函数的this指向
      cxt.fn = this;
      /* 获得传入对象后面的参数
        arguments: [对象,参数1,参数2]
        arguments.slice(1): [参数1, 参数2]
      **/
      var reuslt;
      var args;
      if (arguments[1]) {
        args = [...arguments]. slice(1);
        result = cxt.fn(...args);
      } else {
        result = cxt.fn();
      }
      // 将参数传入函数
      delete cxt.fn;
      return result
    }
    

    apply实现方法

    // 原理相同,但是不同的是,apply接收参数是数组形式,所以只需要获得数组参数即可
    Function.prototype.apply = function (context) {
      var ctx = context || window;
      ctx.fn = this;
      var result;
      if (arguments[1]) {
        result = ctx.fn(... arguments[1]);
      } else {
        result = cxt.fn()
      }
      delete ctx.fn;
      return result
    }
    

    bind实现方法

     // 最后bind实现起来就比较简单,不需要各种传参数之类的,只需要注意当前环境必须是function
    Function.prototype.bind = function (context) {
      if (typeof this !== 'function') {
        throw new TypeError('Error')
      }
      var _this = this
      var args = [...arguments].slice(1)
      // 返回一个函数
      return function F() {
        // 因为返回了一个函数,我们可以 new F(),所以需要判断
        if (this instanceof F) {
          return new _this(...args, ...arguments)
        }
        return _this.apply(context, args.concat(...arguments))
      }
    }
    
    

    3种方法都是能改变this的指向,平时可以根据需求自由选择~
    今天就重温到这里,明天再见😝

    相关文章

      网友评论

          本文标题:前端重学之路——bind、call、apply

          本文链接:https://www.haomeiwen.com/subject/tsfwuqtx.html