美文网首页让前端飞Web前端之路
call,apply,bind区别与实现

call,apply,bind区别与实现

作者: 9eac842c3a81 | 来源:发表于2019-07-16 22:17 被阅读2次

    区别: 指定this,call和apply执行函数,bind不执行

    callapplybind都是为了解决this的指向,callapply都会执行函数,而bind只是绑定this不执行函数。callapply接受参数方式不一样,除了第一个参数都是指定thiscall接受一个参数列表,apply 只接受一个参数数组。

    var obj = {
      value: 1
    }
    function foo(a, b) {
      console.log(a, b)
      console.log(this.value)
    }
    foo.call(obj, 1, 2)
    foo.apply(obj, [1, 2])
    
    // bind 只绑定
    foo.bind(obj, 1, 2)
    

    模拟实现call,apply,bind

    实现思路

    • 不传入第一个参数,则默认为window
    • 改变this指向,让新的对象可以执行该函数。=》给新的对象添加一个函数,执行之后删除

    call的实现

    Function.prototype.myCall = function (context) {
      var context = context || window;  // 传入的新对象
      // 给新对象添加一个属性(方法)
      context.fn = this; // this 指向的是调用myCall方法的函数
      // 取出剩余参数
      var args = [...arguments].slice(1);
      var result = context.fn(...args); // 调用context.fn实则调用myCall方法的函数,但函数this指向了context
      delete context.fn;
      return result
    }
    

    apply的实现

    call方法实现中参数传递方式改为数组形式

    Function.prototype.myApply = function (context) {
      var context = context || window;  // 传入的新对象
      // 给新对象添加一个属性(方法)
      context.fn = this; // this 指向的是调用myCall方法的函数
      // 剩余参数 数组形式
      var result;
      if(arguments[1]) {
        result = context.fn(...arguments);
      } else {
        result = context.fn();
      }
      delete context.fn;
      return result
    }
    

    bind的实现

    this指向,返回一个函数

    Function.prototype.myBind = function (context) {
      var context = context || window;
      var _this = this; 
      var args = [...arguments].slice(1);
      return function () {
        _this.apply(context, args.concat(...arguments))
      }
    }
    

    相关文章

      网友评论

        本文标题:call,apply,bind区别与实现

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