Siri: jQuery: this und $(this)

Hallo,

bei Stackoverflow hab ich zum Thema "Difference between $(this) and this in jquery" folgende Aussage gefunden:

"this is the DOM object, whereas $(this) is the jQuery wrapper around same.

When using this, you can call DOM methods on it, but not jQuery methods. When using $(this), you can call jQuery methods on it, but not DOM methods."

Bei jQuery gibt es folgenden Beispielcode zum Thema Plugins:

  
(function( $ ) {  
   $.fn.showLinkLocation = function() {  
  
     this.filter( "a" ).each(function() {  
       var link = $( this );  
       link.append( " (" + link.attr( "href" ) + ")" );  
     });  
  
     return this;  
   };  
}( jQuery ));

filter("a") ist doch eine jQuery-Methode, oder? Wieso dann this und nicht $(this). Ebenso verstehe ich nicht, warum man this zurückgibt und nicht $(this). Kann mir das jemand erklären? Danke!

Viele Grüße
Siri

  1. Tach!

    bei Stackoverflow hab ich zum Thema "Difference between $(this) and this in jquery" folgende Aussage gefunden:
    "this is the DOM object, whereas $(this) is the jQuery wrapper around same.
    When using this, you can call DOM methods on it, but not jQuery methods. When using $(this), you can call jQuery methods on it, but not DOM methods."

    this ist immer abhängig vom Kontext. Für Funktionen, die von jQuery-Eventhandlern aufgerufen werden, wird this auf das auslösende DOM-Element gesetzt.

    $.fn.showLinkLocation = function() {
         this.filter( "a" ).each(function() {

    filter("a") ist doch eine jQuery-Methode, oder? Wieso dann this und nicht $(this).

    Hier ist der Kontext eine jQuery-Erweiterung, das this bezieht sich auf diese Erweiterung und nicht auf ein DOM-Element.

    Ebenso verstehe ich nicht, warum man this zurückgibt und nicht $(this). Kann mir das jemand erklären? Danke!

    Hat man so entschieden. Irgendwas muss man ja übergeben. Wenn es $(this) wäre und man stattdessen das DOM-Element braucht, wäre das Hinzufügen des jQuery-Wrappers unnötige Arbeit und damit laufzeitverlängernd. Das nackte this zu übergeben und bei Bedarf den Wrapper drumzubauen, ist zwar mehr Arbeit für dich als Anwender, aber insgesamt hat man so nur dann das Wrapper-Hinzufügen im Code, wenn es tatsächlich gebraucht wird.

    dedlfix.

    1. Sorry, Antwort/neue Frage ist hier.

  2. Hallo,

    Danke für die Antwort!

    Das wirft eine neue Frage auf. Ein beliebtes Konstrukt scheint ja zu sein (aus einem Plugin):

    (function ($) {  
      
      $.fn.shareButtons = function (url, options) {  
      
        $(this).addClass("foo");  
      
        // The plugin supports multiple share buttons on the page.  
        // Here we loop the supplied elements and initialize it.  
        this.each(function(i){  
           var elem = $(this);  
      
           // Do something  
      
        }  
      
      
      };  
    	  
    })(jQuery);
    

    Aufgerufen wird das Plugin mit:

    $(function (){  
      $('.socialShare').shareButtons(url, options);  
    }  
    
    

    Das wiederum ziel auf alle Elemente der Klasse socialShare. Wird durch das each im Plugin sozusagen alles doppelt gemoppelt?  $(this).addClass("foo"); gilt ja für alle Elemente dieser Klasse, ohne dass man vorher mit each darüber loopt! Mhmm...

    Viele Grüße
    Siri

    1. Tach!

      Wird durch das each im Plugin sozusagen alles doppelt gemoppelt?

      Mit dem Schreiben von jQuery-Plugins kenne ich mich nicht aus. Wenn du wissen willst, was da wann konkret vorliegt, nimm doch die Entwicklertools der Browser. Setz einen Breakpoint und untersuch dann den Inhalt.

      dedlfix.

    2. $.fn.shareButtons = function (url, options) {
          $(this).addClass("foo");

      Das ist nicht nötig. this.addClass("foo") reicht aus, weil this hier auf das jQuery-Objekt zeigt.

      this.each(function(i){
             var elem = $(this);

      Das ist nötig, weil this hier auf ein DOM-Element zeigt.

      http://api.jquery.com/each/

      $(this).addClass("foo"); gilt ja für alle Elemente dieser Klasse, ohne dass man vorher mit each darüber loopt! Mhmm...

      this.addClass() iteriert automatisch über alle Elemente, die im aktuellen jQuery-Objekt "verpackt" sind.

      Ralf

  3. Hi,

    "this is the DOM object, whereas $(this) is the jQuery wrapper around same.

    Das gilt für Event-Handler, aber das lässt sich nicht verallgemeinern. Was this bedeutet, hängt in JavaScript immer von der Aufrufweise der Funktion.

    $.fn.showLinkLocation = function() {

    this.filter( "a" ).each(function() {
           var link = $( this );
           link.append( " (" + link.attr( "href" ) + ")" );
         });

    return this;
       };

      
    jQuery-Plugins sind neue Methoden von jQuery.prototype. $.fn ist nur eine Abkürzung für jQuery.prototype. Man fügt somit dem Prototyp neue Methoden hinzu:  
      
    ~~~javascript
    jQuery.prototype.meineMethode = function() {  
      console.log('meineMethode', this);  
    };
    

    Gehen wir von einem jQuery-Objekt aus:

    var jQueryObjekt = $('.foo');

    Intern wird new jQuery() aufgerufen, also ein Objekt erzeugt, das von jQuery.prototype erbt.

    jQueryObjekt.meineMethode();

    Das ruft die Plugin-Funktion auf.

    In Objektmethoden verweist "this" auf die Instanz, sofern sie mit objekt.methode() aufgerufen wird. Die Instanz ist hier ein jQuery-Objekt. Ergo zeigt this auf das jQuery-Objekt.

    Daher kannst du direkt this.filter() aufrufen, und alle anderen jQuery-Methoden, die es so gibt. Es ist an dieser Stelle kein weiteres $(this) nötig.

    Das ist übrigens keine jQuery-Eigenheit, sondern so funktioniert Objektorientierung in JavaScript.

    filter("a") ist doch eine jQuery-Methode, oder?

    Ja.

    Wieso dann this und nicht $(this).

    Weil this hier schon das jQuery-Objekt ist, kein DOM-Element.

    Das (erste) DOM-Element wäre über this[0] oder this.get(0) zugänglich.

    Ebenso verstehe ich nicht, warum man this zurückgibt und nicht $(this).

    Das sollte dir nun einleuchten: Damit Chaining möglich ist. Eine jQuery-Methode, die keinen sinnvolleren Rückgabewert hat, gibt wieder das jQuery-Objekt zurück, damit weitere Methodenaufrufe möglich sind. Also hier einfach return this.

    Ralf

    1. Hallo,

      $.fn.showLinkLocation = function() {

      this.filter( "a" ).each(function() {
             var link = $( this );
             link.append( " (" + link.attr( "href" ) + ")" );
           });

      return this;
         };

      
      >   
      
      Danke für deine Erläuterung! Jetzt hat es Klick gemacht! Das $(this) in der Schleife ist ja ein anderes "this", das "äußere" this existiert einfach durch das Gesamtkonstrukt.  
        
      
      > > Ebenso verstehe ich nicht, warum man this zurückgibt und nicht $(this).  
      >   
      > Das sollte dir nun einleuchten: Damit Chaining möglich ist.  
      
      Das man this wegen Chaining zurück gibt hatte ich verstanden. Ich wusste aber nicht, warum man nicht $(this) zurück gibt. Jetzt schon.  
        
      Viele Grüße  
      Siri