2015-05-28 11 views
10

ich bekannt möchte, wenn es eine einheimische Art und Weise, dies zu tun ist:Eine native Weise benutzerdefinierte JavaScript-Funktionen in eine Methode-Anrufe Kette der Zugabe

Object.prototype.chain = function(f) { return f.call(this) } 


function fun1() { 
    doSomethingWithObject(this) 
    return this 
} 

function fun2() { 
    doSomethingElse(this) 
    return this 
} 

someObject 
    .method1('something') 
    .method2() 
    .chain(checkSomething() ? fun1 : fun2) 
    .method3() 

Aber ich fühle mich nicht wie der Prototyp Object Wechsel . Gibt es eine Möglichkeit, dies zu tun, ohne den Prototyp Objects oder die anderen Konstrukteuren zu ändern, die ich (und ist nicht der Entwickler)

Edits:

Ich fühle mich nicht sehr gut erklären, lassen‘ fügen Sie einige Details hinzu:

Was ich tun möchte, ist, einige APIs zu verwenden, die ich nicht definiere. someObject wird wie folgt definiert, mit verkettbar Methoden:

var someObject = { 
    method1: function(val) { 
     // do something 
     return this 
    }, 
    method2: function() { 
     // do something 
     return this 
    }, 
    method3: function() { 
     // do something 
     return this 
    } 
} 

Jetzt stelle ich mir den Code nicht ändern kann, da dieses Objekt aus einer Bibliothek ist, und so will ich nicht zu. Stellen Sie sich dann vor, dass ich Methoden und einige benutzerdefinierte Funktionen (siehe mein erstes Snippet) für viele andere Objekte ketten möchte. Am einfachsten ist es, eine chain Methode an Object.prototype anzuhängen.

Aber ich denke, dass es zu Konflikten in der Zukunft führen könnte. Ich suche nach einer Möglichkeit, dasselbe zu tun, ohne den Prototyp zu berühren.

+1

was meinst du für neative? –

+0

Ich meine, den Object.prototype nicht zu berühren. Ich bin auf der Suche nach einem Javascript bereits für alle Javascript-Objekte – niahoo

+0

Nun, solange die Funktion Teil des ursprünglichen Objekts ('myObject') ist und die Funktion' myObject' zurückgibt ('return this', in der Regel) nach seiner Fertigstellung , können Sie eine andere Funktion verketten. Ansonsten würde ich sagen - tu das nicht. Sie werden feststellen, dass es nichts Nützliches bringt. –

Antwort

2

Der Wrapper ist etwas, das jedes Objekt umschließt, um es mit "Verkettung" kompatibel zu machen, und fügt eine weitere Kettenmethode hinzu, die es ermöglicht, externe Funktionen zu verbinden und trotzdem die Verkettung zu erhalten.

prüfen dieses Beispiel:

function myObj() { 
    this.state = { 
     a: 1 
    }; 
    this.method1 = function() { 
     console.log("1"); 
    } 
    this.method2 = function() { 
     console.log("2"); 
    } 
    this.method3 = function() { 
     console.log("3"); 
    } 
    this.method4 = function() { 
     console.log(this.state); 
    } 
} 

function objectChainWrapper(obj) { 
    this.chain = function (fn) { 
     fn.call(obj); 
     return this; 
    } 

    for (var prop in obj) { 
     if (obj.hasOwnProperty(prop) && typeof obj[prop] == 'function') { 
      this[prop] = (function (methodName) { 
       return function() { 
        obj[methodName].call(obj); 
        return this; 
       } 
      }(prop)) 
     } 
    } 
} 

var obj = new myObj(); 
var wrapper = new objectChainWrapper(obj); 
var chainMethod = function(){ console.log('chain') }; 
var chainMethodState = function(){ console.log(this.state) }; 
wrapper.method1().method2().chain(chainMethodState).method3().chain(chainMethod).method4(); 

JSFIDDLE.

+0

Gibt es einen Grund für den Wrapper? Ich meine, wenn die Funktionen 'this' zurückgeben würden, dann müssten Sie keinen Wrapper verwenden, Sie könnten einfach die Kette direkt von der Funktion verwenden. Am Ende würde Ihre Kette dann wie folgt aussehen: 'myObj.method1(). Method2(). Method3();' Im Wesentlichen ist der Wrapper macht "Return this" zu jeder Funktion hinzufügen sowieso. – Jay

+0

@Jay - der Wrapper nimmt ein Objekt und "schreibt" seine Methoden neu, so dass sie "this" zurückgeben und die Verkettung erlauben. Es ist eine gute Möglichkeit, Ihre Objekte Methoden zu protokollieren oder zu ändern, ohne Ihre Objekte zu ändern. –

+0

Hallo; Danke für deine Antwort! Da ich gerne benutzerdefinierte Funktionen in die Aufrufkette einfügen würde, glaube ich nicht, dass Ihr Code dies zulassen würde. Aber eigentlich könnte ich das Objekt zuerst wickeln und die Chain-Methode zum Dekorator hinzufügen. Guter Punkt – niahoo

5

Ich bin überrascht, dass es keine Antworten auf diese um ehrlich zu sein.

Es gibt viele Möglichkeiten, die Verkettung nativ einzuführen. Ich benutze gerne die revealing module pattern.

So erstelle ich ein Basismodell (Gehen Sie weiter und schmeißen Sie dies in Ihrem Chrome Firefox Konsole)

var Dog = function(name) { 
    var self = this; 
    this.name = name; 


    var core = { 
      getName:function(){ 
       return self.name; 
      } 
     }; 

    this.movement = function(){  //this function will be exposed including its returned functions for chaining  
     console.log(self.name + " is getting restless... "); 

     var jump = function(){ 
      console.log(self.name + " jumps around "); 
      return this //returns the movement scope 
     }; 
     var run = function(){ 
      console.log(self.name + " has decided to run"); 
      return this //returns the movement scope 
     }; 

     return { 
      jump:jump, 
      run:run   
     }; 

    }  
    console.log("A Pup has been born, we shall call him... " + name); 
    return{ 
     movement:self.movement //only .movement is exposed to the outside world 
    }; 
    } 

Jetzt einen neuen Hund var p = new Dog("doggyName");

jetzt mit erstellen, können Sie Kettenfunktionen. Versuchen Sie:

Sie sollten die Konsole geloggten Text, der mit jeder Funktion entspricht.

Durch die Rückgabe des Bereichs nach der Ausführung Ihrer Bewegungsfunktion geben Sie die zusätzlichen Funktionen frei, die in diesem Bereich zurückgegeben werden (siehe die Kommentare im Code). Diese können dann am Ende Ihrer aktuellen Funktion angekettet werden, sofern sie sich im selben Umfang befinden. Auf diese Weise können Sie bestimmte Teile Ihres Codes umgrenzen. Zum Beispiel mit diesem Hund, alle Bewegung ist auf self.movement Bereich beschränkt, könnten Sie alle essen beschränkt auf self.eat und so weiter

Read up on the revealing module pattern. Obwohl dies nicht der einzige Weg ist, dies zu tun.

+0

Das ist hilfreich. Interessiert, andere Wege zu kennen. – aksappy

+0

Hallo, danke für deine Antwort. Ich habe einige Änderungen an meiner Frage vorgenommen, da ich denke, dass es nicht gut geschrieben wurde. Ihr Beispiel ist interessant, ich benutze dieses Muster (aber ich kannte den Namen nicht, danke), aber es erlaubt keine benutzerdefinierten Funktionen in die Kette einzuführen. – niahoo

Verwandte Themen