美文网首页
Underscore源码阅读:bind

Underscore源码阅读:bind

作者: San十二 | 来源:发表于2018-11-10 21:21 被阅读0次

bind函数

参考:JavaScript深入之bind的模拟实现

bind(function, object, *arguments):绑定函数 function 到对象 object 上, 也就是无论何时调用函数, 函数里的 this 都指向这个 object。

我们先看上面的参考博文的实现,其中有几个要点:

  1. bind的基本实现(用闭包保存bind传进来的上下文)
  2. bind是可以传部分或者全部参数的
  3. bind后的函数是依旧可以当做构造函数来使用并且忽略bind提供的this

再结合《你不知道的JavaScript(上)》里的bind,我们可以得到这样一个bind

Function.prototype.myBind = function (context) {
  context = Object(context) || window;
  var self = this;
  var args = [].slice.call(arguments, 1);

  var constructor = function () {
    args = args.concat([].slice.call(arguments));
    if (this instanceof self) {
      // 说明正在使用new
      return self.apply(this, args);
    } else {
      // 普通的bind使用方法
      return self.apply(context, args);
   }
  }
  constructor.prototype = Object.create(self.prototype);
  return constructor;
}

然后我们来看看underscore中的_.bind

  _.bind = function (func, context) {
    // nativeBind
    if (nativeBind && func.bind === nativeBind) return nativeBind.apply(func, slice.call(arguments, 1));
    // 上下文校验
    if (!_.isFunction(func)) throw new TypeError('Bind must be called on a function');
    // 保存部分参数
    var args = slice.call(arguments, 2);
    var bound = function () {
      return executeBound(func, bound, context, this, args.concat(slice.call(arguments)));
    };
    return bound;
  };

我们也看到bind函数实现的核心是executeBound函数,它有5个参数

  • funcbind的目标函数
  • boundbind的返回函数
  • context:绑定上下文
  • this:执行上下文
  • args:执行参数
    明白了参数的意义,我们再来看executeBound的实现
  var executeBound = function (sourceFunc, boundFunc, context, callingContext, args) {
    if (!(callingContext instanceof boundFunc)) return sourceFunc.apply(context, args);
    var self = baseCreate(sourceFunc.prototype);
    var result = sourceFunc.apply(self, args);
    if (_.isObject(result)) return result;
    return self;
  };

其实思路就跟之前的bind函数是一样的了。

  1. 判断执行上下文是否是new赋值的新this
  2. 如果不是,当做普通的bind返回函数
  3. 如果是,则需要当做构造函数使用,就需要添加prototype和检验返回结果
  4. baseCreate添加原型,result检验构造函数是否有返回值;
  5. 如果这个返回值是对象,就返回这个对象;否则返回构造函数执行的结果。

于是发现,Underscore源码实现的bind函数,跟我们之前实现的是一样的。

相关文章

网友评论

      本文标题:Underscore源码阅读:bind

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