封装call apply bind函数

三者的区别

如果当时就想执行,参数是数组用apply否则用call;如果是调用才执行,则用bind

🚩一、call函数

模拟实现第一步:整体思路

Function.prototype.call2=function(context){
   context.fn=this; //1、将函数(谁调用 即this)设为对象(参数)的属性
   context.fn(); //2、执行该函数
   delete context.fn;//3、删除对象中的函数属性
}

模拟实现第二步:加上参数

Function.prototype.myCall = function (context, ...args) {
  context = context || window;
  context.fn = this;
  let result = context.fn(...args);
  delete context.fn;
  return result;
}

function a(m, n) {
  return console.log(this.name + ' ' + m + ' ' + n)
}

const b = {
  name: 'kong'
};

a.myCall(b, 7, 8);

运行结果:

🚩二、apply函数

和call的思路是一样的,注意一下参数的处理即可

Function.prototype.myApply = function (context, arr) {
  context = context || window;
  context.fn = this;
  let result
  if (!arr) {
    result = context.fn()
  } else {
    result = context.fn(arr)
  }
  delete context.fn
  return result
}

function a(arr) {
  return console.log(this.name + ' ' + arr)
}

const b = {
  name: 'kong'
};

a.myApply(b, [7, 8]);
a.myApply(b);

运算结果:

🚩三、bind函数

  • 因为 bind 的使用方法是 某函数.bind(某对象,...剩余参数),所以需要在 Function.prototype 上进行编程
  • 将传递的参数中的某对象和剩余参数使用 apply 的方式在一个回调函数中执行即可
  • 要在第一层获取到被绑定函数的 this,因为要拿到那个函数用 apply
Function.prototype.myBind = function (that, ...args) {
  // 注意:这里不能用箭头函数 因为箭头函数中的this对象,就是定义时所在的对象,而不是使用时所在的对象。
  const funcThis = this;
  return (..._args) => {
    // 注意箭头函数主体中只有一条语句时 可以省略return
    return funcThis.apply(that, args.concat(_args));
  }

}

function a(m, n, o) {
  return console.log(this.name + ' ' + m + ' ' + n + ' ' + o)
}

const b = {
  name: 'kong'
};

// a.myBind(b, 7, 8)(9);
a.myBind(b, 7, 8);

运行结果:

posted @ 2020-07-27 16:26  享码yy  阅读(197)  评论(0编辑  收藏  举报