JavaScript学習ノート:Function.prototype.bind()

10386 ワード

https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Object/Function/bind
1.バインディング関数とは?
bind()メソッドは、この新しい関数が呼び出されたときに提供される値に設定され、そのパラメータリストの前の項目が作成時に指定されたパラメータのシーケンスにセットされた新しい関数を作成します.
  • 初めてこの話を見た時、読めませんでした.次の例を見てやっと分かりました.
    var module = {
        x: 42,
        getX: function(){
            return this.x;
        }
    };
    
    var unboundGetX = module.getX;
    // unboundGetX        module.getX     ,       unboundGetX()      this        ,    module
    console.log('unboundGetX=', unboundGetX()); //   unboundGetX= undefined 
    
    //            ,     this    module,    ?
    var boundGetX = module.getX.bind(module);
    //         boundGetX()     ,this    module 
    console.log('boundGetX=', boundGetX()); //   boundGetX= 42
    
    この例はJavaScriptの新米がよく犯している誤りを示しています.一つの方法を対象から取り出してから呼び出します.希望方法のthisは元のオブジェクトです.
  • は、なぜビッドが必要なのかを説明しています.thisの値が不確定です.
  • は元の関数と元のオブジェクトから結合関数を作成すると、この問題を綺麗に解決できます.
  • bind()の最も簡単な使い方は、関数を作成して、この関数をどのように呼び出しても同じthis値があるようにします.
    2.バインディング関数はどうやって作成しますか?
    fun.bind(thisArg[,arg 1[,arg 2]])
  • thisArg:結合関数を呼び出したときに、thisパラメータとしてターゲット関数に渡す値.
  • arg 1,arg 2,…バインディング関数が起動されると、これらのパラメータは、実際の参照の前にバインディングされた方法に渡される.
  • ビッドの結果は何ですか?戻り値は何ですか?
  • 元関数のコピー
  • 改造した元関数コピー
  • は、指定されたthis値と初期化パラメータによって改造された元関数コピー
  • である.
    結合関数の内部原理解析
    bind()は新しい関数を作成します.結合関数です.結合関数は元の関数と同じ関数を持つ.
  • バインディング関数の呼び出しは、通常、元の関数の実行につながる.
  • バインディング関数は以下の内部属性を持っています.
  • -[BoundTarget Function]-結合された関数オブジェクト
  • [[BoundThis]-バインディング関数の呼び出し時に常にthis値として渡される値.
  • [BoundAgments]−結合関数の呼び出しの最初のパラメータとして要素を使用する値リスト.
  • [[Call]-このオブジェクトに関連するコードを実行します.関数で式を呼び出します.内部法のパラメータはthis値であり、式を呼び出して関数に渡すパラメータリストを含む.
  • バインディング関数を呼び出すと、内部メソッドCallを呼び出します.このうち、boundThisは[BoundThis]であり、argsは[[BoundAgments]]であり、踵関数は伝達の他のパラメータを呼び出します.
    バインディング関数は、new演算子構造を使用することもできます.目的関数が既に構築されているようです.提供されたthis値は無視されますが、前置パラメータはアナログ関数に提供されます.
    3.バインディング関数の例
    3.1偏関数
    bind()のもう一つの用途は,一つの関数が予め設定された初期パラメータを持つようにすることである.これらのパラメータは、ターゲット関数のパラメータリストの開始位置に挿入され、バインディング関数に伝達されるパラメータは、それらの後に続く.
    function list() {
        return Array.prototype.slice.call(arguments);
    }
    
    var list1 = list(1, 2, 3); // [1, 2, 3]
    
    //       :         
    var leadingList = list.bind(null, 37);
    
    var list2 = leadingList(); // [37]
    var list3 = leadingList(1, 2, 3); // [37, 1, 2, 3]
    
    このように部分パラメータを指定して新たに定められた関数を生成する形が偏関数です.
    3.2 setTimeoutを配合する
    デフォルトでは、window.setTimeout()を使うと、thisキーワードはwindow(またはグローバル)オブジェクトを指します.クラスの方法を使用する場合、インスタンスを継続するために、this引用クラスの実例が必要となるかもしれません.
    function LateBloomer() {
        this.petalCount = Math.ceil(Math.random() * 12) + 1;
    }
    
    //         bloom   ,1      declare   
    LateBloomer.prototype.bloom = function() {
        //          2    !
        window.setTimeout(this.declare.bind(this), 1000);
        //          undefined    !
        // window.setTimeout(this.declare, 1000); //     
    };
    
    LateBloomer.prototype.declare = function() {
        console.log('         ' + this.petalCount + '    !');
    };
    
    var flower = new LateBloomer();
    flower.bloom();
    
    this値が不確定で、this値を指定するところは全部bindで解決しますよね?これは私の推論です.試してみてもいいです.