サーチ…


メソッドチェイン

メソッド連鎖は、コードを単純化して美しくするプログラミング戦略です。メソッド連鎖は、オブジェクトの各要素が単一の要素を返すのではなく、オブジェクト全体を返すようにすることによって行われます。例えば:

function Door() {
    this.height = '';
    this.width = '';
    this.status = 'closed';
}

Door.prototype.open = function() {
    this.status = 'opened';
    return this;
}

Door.prototype.close = function() {
    this.status = 'closed';
    return this;
}
Door.prototype.setParams = function(width,height) {
    this.width = width;
    this.height = height;
    return this;
}

Door.prototype.doorStatus = function() {
    console.log('The',this.width,'x',this.height,'Door is',this.status);
    return this;
}

var smallDoor = new Door();
smallDoor.setParams(20,100).open().doorStatus().close().doorStatus();

Door.prototype各メソッドはDoor.prototype返します。 this 、そのDoorオブジェクトのインスタンス全体を参照します。

チェーン化可能なオブジェクトの設計とチェーニング

ChainingとChainableは、オブジェクト関数への呼び出しが自己または別のオブジェクトへの参照を返すようにオブジェクトビヘイビアを設計するための設計方法で、変数の保持を参照せずに呼び出しステートメントが多数の呼び出しを連鎖できるようにしますオブジェクト/ s。

連鎖可能なオブジェクトは連鎖可能であると言われています。チェーン化可能なオブジェクトを呼び出す場合は、戻されたすべてのオブジェクト/プリミティブが正しいタイプであることを確認する必要があります。連鎖可能なオブジェクトが正しい参照を返さないようにするには1回しかかかりません( return thisreturn thisを忘れるのは簡単です)、APIを使用する人は信頼を失い連鎖を避けます。チェーン化可能なオブジェクトは、すべてでもなくてもかまいません(チェーン化可能なオブジェクトではなく、パーツであっても)。その関数の一部しかない場合、オブジェクトは連鎖可能と呼ばれるべきではありません。

チェーン化可能に設計されたオブジェクト

function Vec(x = 0, y = 0){
    this.x = x;
    this.y = y;
    // the new keyword implicitly implies the return type 
    // as this and thus is chainable by default.
}
Vec.prototype = {
    add : function(vec){
        this.x += vec.x;
        this.y += vec.y;
        return this; // return reference to self to allow chaining of function calls
    },
    scale : function(val){
        this.x *= val;
        this.y *= val;
        return this; //  return reference to self to allow chaining of function calls
    },
    log :function(val){
        console.log(this.x + ' : ' + this.y);
        return this;
    },
    clone : function(){
        return new Vec(this.x,this.y);
    }
}

チェーンの例

var vec = new Vec();
vec.add({x:10,y:10})
    .add({x:10,y:10})
    .log()             // console output "20 : 20"
    .add({x:10,y:10})
    .scale(1/30)
    .log()             // console output "1 : 1"
    .clone()           // returns a new instance of the object
    .scale(2)          // from which you can continue chaining
    .log()

戻り値の型にあいまいさを生じさせない

すべての関数呼び出しが有用な連鎖可能型を返すわけではなく、常に自己への参照を返すわけでもありません。これは、名前の常識的な使用が重要な場合です。上の例では、関数呼び出し.clone()はあいまいではあり.clone() 。他の例は、 .toString()は文字列が返されることを意味します。

連鎖可能オブジェクト内のあいまいな関数名の例。

 // line object represents a line
 line.rotate(1)
    .vec();  // ambiguous you don't need to be looking up docs while writing.

 line.rotate(1)
    .asVec()    // unambiguous implies the return type is the line as a vec (vector)
    .add({x:10,y:10)
 // toVec is just as good as long as the programmer can use the naming 
 // to infer the return type

構文規則

連鎖するときの正式な使用構文はありません。コンベンションでは、短くても1行で呼び出しを連鎖させるか、新しい行に連鎖して、参照されたオブジェクトの1つのタブを新しい行のドットでインデントします。セミコロンの使用はオプションですが、チェーンの終わりを明確に示すことによって助けになります。

  vec.scale(2).add({x:2,y:2}).log();  // for short chains

  vec.scale(2)     // or alternate syntax
      .add({x:2,y:2})
      .log();  // semicolon makes it clear the chain ends here

  // and sometimes though not necessary
  vec.scale(2)     
      .add({x:2,y:2})
      .clone()    // clone adds a new reference to the chain
           .log(); // indenting to signify the new reference

  // for chains in chains
  vec.scale(2)     
      .add({x:2,y:2})
      .add(vec1.add({x:2,y:2})  // a chain as an argument 
           .add({x:2,y:2})      // is indented
           .scale(2))
      .log();

  // or sometimes 
  vec.scale(2)     
      .add({x:2,y:2})
      .add(vec1.add({x:2,y:2})  // a chain as an argument 
           .add({x:2,y:2})      // is indented
           .scale(2)
      ).log();   // the argument list is closed on the new line

不正な構文

   vec          // new line before the first function call
      .scale()  // can make it unclear what the intention is
      .log();

   vec.          // the dot on the end of the line
      scale(2).  // is very difficult to see in a mass of code
      scale(1/2); // and will likely frustrate as can easily be missed
                  // when trying to locate bugs

課題の左側

チェーンの結果を割り当てると、最後に返されたコールまたはオブジェクト参照が割り当てられます。

 var vec2 = vec.scale(2)
                .add(x:1,y:10)
                .clone();   // the last returned result is assigned
                                // vec2 is a clone of vec after the scale and add

上記の例では、 vec2にチェーン内の最後の呼び出しから返された値が割り当てられています。この場合、スケールの後にvecコピーが追加され、追加されます。


概要

変更の利点は、よりメンテナンス可能なコードが明確になります。一部の人はそれを好み、APIを選択する際に連鎖可能な要件を作成します。また、中間結果を保持する変数を作成する必要がないため、パフォーマンス上の利点もあります。最後の言葉では、連鎖可能なオブジェクトは従来の方法でも使用できるので、連鎖可能なオブジェクトを連鎖させることによって連鎖を強制することはありません。



Modified text is an extract of the original Stack Overflow Documentation
ライセンスを受けた CC BY-SA 3.0
所属していない Stack Overflow