Suche…


Method Chaining

Method Chaining ist eine Programmierstrategie, die Ihren Code vereinfacht und verschönert. Die Verkettung von Methoden erfolgt, indem sichergestellt wird, dass jede Methode eines Objekts das gesamte Objekt zurückgibt, anstatt ein einzelnes Element dieses Objekts zurückzugeben. Zum Beispiel:

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();

Beachten Sie, dass jede Methode in Door.prototype this Door.prototype zurückgibt, der sich auf die gesamte Instanz dieses Door Objekts bezieht.

Verkettbares Objektdesign und Verkettung

Chaining and Chainable ist eine Entwurfsmethodik, die zum Entwerfen von Objektverhalten verwendet wird, sodass Aufrufe an Objektfunktionen Verweise auf sich selbst oder ein anderes Objekt zurückgeben, wodurch Zugriff auf zusätzliche Funktionsaufrufe ermöglicht wird, die es der aufrufenden Anweisung ermöglichen, viele Aufrufe miteinander zu verketten, ohne auf die Variablenhaltung verweisen zu müssen Die Objekte.

Objekte, die verkettet werden können, werden als kettenbar bezeichnet. Wenn Sie ein Object Chainable aufrufen, sollten Sie sicherstellen, dass alle zurückgegebenen Objekte / Primitive den richtigen Typ haben. Es dauert nur eine Zeit, bis Ihr verkettbares Objekt nicht die korrekte Referenz zurückgibt (leicht zu vergessen, return this ), und die Person, die Ihre API verwendet, verliert das Vertrauen und vermeidet die Verkettung. Verkettbare Objekte sollten alles oder nichts sein (kein verkettbares Objekt, auch wenn Teile vorhanden sind). Ein Objekt sollte nicht als verkettbar bezeichnet werden, wenn es nur einige seiner Funktionen gibt.

Objekt, das verkettet werden kann

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);
    }
}

Verkettung Beispiel

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()

Erstellen Sie keine Mehrdeutigkeit im Rückgabetyp

Nicht alle Funktionsaufrufe geben einen nützlichen verkettbaren Typ zurück, oder sie geben immer einen Verweis auf sich selbst zurück. Dies ist der Punkt, an dem der gesunde Menschenverstand der Benennung wichtig ist. Im obigen Beispiel ist der Funktionsaufruf .clone() eindeutig. Andere Beispiele sind .toString() impliziert, dass eine Zeichenfolge zurückgegeben wird.

Ein Beispiel für einen mehrdeutigen Funktionsnamen in einem verkettbaren Objekt.

 // 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

Syntaxkonvention

Beim Verketten gibt es keine formale Verwendungssyntax. Die Konvention besteht darin, die Anrufe entweder in einer einzigen Zeile zu verketten, wenn sie kurz ist, oder in der neuen Zeile, die um einen Tab eingerückt ist, aus dem referenzierten Objekt mit dem Punkt in der neuen Zeile zu verketten. Die Verwendung des Semikolons ist optional, hilft jedoch, das Ende der Kette eindeutig zu kennzeichnen.

  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

Eine schlechte Syntax

   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

Linke Seite der Zuordnung

Wenn Sie die Ergebnisse einer Kette zuweisen, wird der letzte zurückgehende Aufruf oder die Objektreferenz zugewiesen.

 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

Im obigen Beispiel wird vec2 der Wert zugewiesen, der vom letzten Aufruf in der Kette zurückgegeben wurde. In diesem Fall wäre das eine Kopie von vec nach dem Skalieren und Hinzufügen.


Zusammenfassung

Der Vorteil der Änderung ist klarer, wartungsfähiger Code. Manche Leute bevorzugen es und machen die Auswahl einer API zur Verkettung erforderlich. Es gibt auch einen Leistungsvorteil, da Sie vermeiden müssen, Variablen für Zwischenergebnisse erstellen zu müssen. Das letzte Wort ist, dass verkettbare Objekte auch auf herkömmliche Weise verwendet werden können, sodass die Verkettung nicht erzwungen wird, indem ein Objekt verkettet wird.



Modified text is an extract of the original Stack Overflow Documentation
Lizenziert unter CC BY-SA 3.0
Nicht angeschlossen an Stack Overflow