js中bind函数的实现

今天研究了一下es5中的bind函数如何用es3的语法来实现,下面是一个简单的bind函数实现:

bind函数

Function.prototype.bind=function(oThis){
    var self=this;
    var args=Array.prototype.slice.call(arguments,1);
    var result=function(){
        return self.apply(oThis,args.concat(Array.prototype.slice.call(arguments)));
    };

    var temp=function(){};
    temp.prototype=this.prototype;
    result.prototype=new temp();
    return result;
};

测试代码

var A={
    name: 'jc',
    print: function(title){
        console.log(title+this.name);
    }
};

var func=A.print.myBind(A);
func('red');   //jcred

分析

整个bind函数一共做了两件事:

  1. 首先通过数组的原型方法把bind函数参数中除了oThis对象以外的参数保存到args中,然后再讲args和调用函数传入参数列表合并,并通过调用Function.prototype.apply方法将oThis绑定到调用函数的this上,并传入合并后的参数列表。

  2. 因为调用apply方法返回了一个新的函数对象,丢失了原函数对象的原型属性,所以还要将新的函数对象的prototype属性引用原函数对象的原型对象。

  3. 之所以不采用result.prototype=this.prototype这种写法,而是使用了一个中间层对象temp,是因为不想通过修改result.prototype就修改了原函数对象的原型对象。

附上bind函数官方文档的实现

if (!Function.prototype.bind) {
  Function.prototype.bind = function (oThis) {
    if (typeof this !== "function") {
      // closest thing possible to the ECMAScript 5 internal IsCallable function
      throw new TypeError("Function.prototype.bind - what is trying to be bound is not callable");
    }

    var aArgs = Array.prototype.slice.call(arguments, 1), 
        fToBind = this, 
        fNOP = function () {},
        fBound = function () {
          return fToBind.apply(this instanceof fNOP && oThis
                                 ? this
                                 : oThis || window,
                               aArgs.concat(Array.prototype.slice.call(arguments)));
        };

    fNOP.prototype = this.prototype;
    fBound.prototype = new fNOP();

    return fBound;
  };
}

你可能感兴趣的:(js中bind函数的实现)