探索bind原理,手写bind

22 阅读1分钟
1. 定义
  • 根据MDN介绍: Function.prototype.bind() :bind() 方法创建一个新的函数,在 bind() 被调用时,这个新函数的 this 被指定为 bind() 的第一个参数,而其余参数将作为新函数的参数,供调用时使用;
  • 语法:function.bind(thisArg[, arg1[, arg2[, ...]]])
2. 特性
  • bind方法会返回一个新的函数;
  • 新函数的this指向为调用bind方法时传入的第一个参数;
  • 调用bind函数时,可以传入多个参数,从第二个参数开始都作为函数运行时的参数;
  • 后面可以继续调用新函数,并支持传入参数,新函数执行时可以将第一次bind绑定时的参数(除了第一个参数作为新的this指向),与后面新函数调用时传入的参数合并,供新函数调用时使用;
3. 在Function原型上手写bind
Function.prototype.mybind = function (asThis) {
  // 使用伪数组arguments缓存接收的参数
  var slice = Array.prototype.slice; // 数组原型上的slice函数
  var args = slice.call(arguments, 1); // 实现arguments使用数组slice方法

  var fn = this;
  if (typeof fn !== 'function') {
    throw new Error('调用方this必须是一个函数')
  }
  // 返回一个方法: 执行之前的方法
  // 拼接后续的参数
  function inner() {
    // 判断当前函数是否是new出来的(此时作为构造函数)
    var isNew = this.constructor === inner;
    // 参数汇总
    var innerArgs = slice.call(arguments)
    args = args.concat(innerArgs);
    // 方法执行,并返回原来函数的返回值
    // call/apply 改变this: asThis
    // new出来(即作为构造函数)传函数this
    // 不是的话传之前的参数
    // return fn.apply(isNew ? this : asThis, args)
    return fn.call(isNew ? this : asThis, ...args)
  }
  return inner;
}