jsの中でbind関数の実現

1975 ワード

今日はS 5の中のbind関数がどうやってes 3の文法で実現されるかを研究しました.以下は簡単な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関数は全部で二つのことをしました.
  • は、まず、配列のプロトタイプ法により、bind関数パラメータのうち、oThisオブジェクト以外のパラメータをargsに保存し、次に、argsと呼び出し関数がパラメータリストに統合され、Funtion.prototype.appyを呼び出すことにより、呼び出し関数のthisにoThisをバインドし、統合後のパラメータリストに入る.
  • は、appyメソッドを呼び出して新しい関数オブジェクトを返したため、元の関数オブジェクトのプロトタイプ属性が失われたため、新しい関数オブジェクトのプロトタイプ属性を元の関数オブジェクトのプロトタイプオブジェクトに参照する必要があります.
  • は、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;
      };
    }