2009-07-08 6 views
16

Ich versuche, die Prinzipien der Funktion jQuery-Stil-Funktion in meinem Kopf gerade zu verketten. Damit meine ich:Wie funktioniert die grundlegende Verknüpfung von Objekten/Funktionen in Javascript?

var e = f1('test').f2().f3(); 

Ich habe ein Beispiel zu arbeiten, während ein anderes nicht funktioniert. Ich werde diese unten posten. Ich möchte immer die grundlegenden Prinzipien lernen, wie etwas funktioniert, damit ich darauf aufbauen kann. Bis jetzt hatte ich nur ein flüchtiges und leises Verständnis davon, wie Verkettung funktioniert, und ich stoße auf Fehler, die ich nicht intelligent lösen kann.

Was ich weiß:

  1. Funktionen haben sich zurückzukehren, auch bekannt als "zurückkommen";
  2. Verkettungsfunktionen müssen sich in einer übergeordneten Funktion befinden, aka in jQuery, .css() ist eine Untermethode von jQuery(), daher jQuery(). Css();
  3. Die Elternfunktion sollte sich selbst oder eine neue Instanz von sich selbst zurückgeben.

Dieses Beispiel arbeitete:

var one = function(num){ 
    this.oldnum = num; 

    this.add = function(){ 
     this.oldnum++; 
     return this; 
    } 

    if(this instanceof one){ 
     return this.one;  
    }else{ 
     return new one(num);  
    } 
} 
var test = one(1).add().add(); 

Aber dieses nicht:

var gmap = function(){ 

    this.add = function(){ 
     alert('add'); 

     return this;  
    } 

    if(this instanceof gmap) { 
     return this.gmap; 
    } else{ 
     return new gmap(); 
    } 

} 
var test = gmap.add(); 
+6

Die Funktionen geben nicht selbst zurück, sie geben das Objekt zurück, das die verketteten Methoden unterstützt. Im jQuery-Fall wird der Knoten bearbeitet. – drudru

+1

Lassen Sie jede Funktion mit einem 'return this;' enden. –

+0

@MarcB - Ich weiß, aber wie? –

Antwort

32

In JavaScript-Funktionen sind Objekte erster Klasse. Wenn Sie eine Funktion definieren, ist dies der Konstruktor für dieses Funktionsobjekt. Mit anderen Worten:

var gmap = function() { 
    this.add = function() { 
     alert('add'); 
    return this; 
    } 

    this.del = function() { 
     alert('delete'); 
     return this; 
    } 

    if (this instanceof gmap) { 
     return this.gmap; 
    } else { 
     return new gmap(); 
    } 
} 
var test = new gmap(); 
test.add().del(); 

Durch die

new gmap();
auf die Variable Test Zuordnung haben Sie nun ein neues Objekt konstruiert, dass „erbt“ alle Eigenschaften und Methoden aus dem gmap() Konstruktor (Klasse). Wenn Sie das obige Snippet ausführen, sehen Sie eine Warnung für "hinzufügen" und "löschen".

In den obigen Beispielen bezieht sich "this" auf das Fensterobjekt, sofern Sie die Funktionen nicht in eine andere Funktion oder ein anderes Objekt einfügen.

Chaining ist schwierig für mich zu verstehen, zumindest war es für mich, aber sobald ich es verstanden habe, realisierte ich, wie mächtig ein Werkzeug sein kann.

4

Leider muss die direkte Antwort "nein" sein. Auch wenn Sie die bestehenden Methoden außer Kraft setzen können (die Sie wahrscheinlich in vielen UAs kann, aber ich vermute, kann nicht in IE), dann würden Sie noch mit fiesen Umbenennungen stecken:

HTMLElement.prototype.setAttribute = function(attr) { 
    HTMLElement.prototype.setAttribute(attr) //uh-oh; 
} 

Das Beste, was Sie wahrscheinlich weg konnte mit einen anderen Namen verwendet:

HTMLElement.prototype.setAttr = function(attr) { 
    HTMLElement.prototype.setAttribute(attr); 
    return this; 
} 
+0

Sieht so aus, als würde ich bei jQuery zum Verketten bleiben! –

+1

Bitte beachten Sie diese Antwort zu [eine andere Frage] (http://stackoverflow.com/questions/10965781) – kojiro

1

um „Rewrite“ eine Funktion, aber immer noch die ursprüngliche Version nutzen zu können, müssen Sie zuerst die ursprüngliche Funktion zu einer anderen variablen zuweisen. Nehmen wir ein Beispiel Objekt:

function MyObject() { }; 

MyObject.prototype.func1 = function(a, b) { }; 

Neuschreiben func1 für Verkettbarkeit, dies tun:

MyObject.prototype.std_func1 = MyObject.prototype.func1; 
MyObject.prototype.func1 = function(a, b) { 
    this.std_func1(a, b); 
    return this; 
}; 

hier ein working example ist. Sie müssen diese Technik nur bei allen Standardobjekten anwenden, von denen Sie glauben, dass sie verkettet werden müssen.

Bis Sie all diese Arbeit tun, könnten Sie erkennen, dass es bessere Wege zu erreichen, was Sie versuchen, eine Bibliothek zu tun, wie mit den bereits in Verkettbarkeit gebaut hat. * hust * jQuery * hust *

+0

Hier ist eine allgemeine Lösung: http://stackoverflow.com/a/15797662/162793 – sheldonh

-3

Rufen Sie einfach die Methode als var test = gmap(). add();

als gmap ist eine Funktion keine Variable

+0

Dies wird nicht funktionieren weil 'add' nicht in' gmap() 'definiert ist, sondern nur in' new gmap() '. –

0

Lassen Sie mich zunächst sagen, dass ich das in meinen eigenen Worten zu erklären bin.

Die Methodenverkettung ruft eine Methode des Objekts auf, die von einer anderen Funktion/Methode zurückgegeben wird. zum Beispiel (unter Verwendung von jquery):

$('#demo'); 

Dieser jquery Funktion wählt und gibt das DOM-Element mit der ID-Demo ist ein jquery Objekt. Wenn das Element ein Textknoten (Element) wäre, könnten wir eine Methode des zurückgegebenen Objekts verketten. zum Beispiel:

$('#demo').text('Some Text'); 

Also, solange eine Funktion/Methode ein Objekt zurückgibt, können Sie Kette ein Verfahren des zurückgegebenen Objekts zur ursprünglichen Aussage.

Warum Letztere nicht funktionieren, achten Sie darauf, wo und wann das Schlüsselwort this verwendet wird. Es ist höchstwahrscheinlich ein Kontextproblem. Wenn Sie this aufrufen, stellen Sie sicher, dass sich this auf dieses Funktionsobjekt selbst bezieht, nicht auf das Fensterobjekt/den globalen Bereich.

Hoffe, dass hilft.

Verwandte Themen