Jeena Paradies: Pythons "self" in JS

Hallo,

In Python gibt es ja dieses "self" das sich immer auf das aktuelle Objekt bezieht:

class JavaScriptObjects:  
    def has_class(self, classname):  
        return self.class_name == classname;

Auch bei PHP gibt es das $this, was auch immer auf das aktuelle Objekt verweist:

class JavaScriptObjects {  
    function has_class($classname) {  
        return $this->class_name == $classname;  
    }  
}

Wie kann ich auf das aktuelle Objekt in JavaScript zugreifen? Mein Ansatz ist ja falsch, weil "this" beim definieren natürlich auf [Window Object] zeigt.

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"  
 "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">  
<html>  
 <head>  
  <meta http-equiv="Content-type" content="text/html; charset=utf-8">  
  <title>JS-Test</title>  
  <script type="text/javascript" charset="utf-8">  
   [code lang=javascript]Object.prototype.hasClass = function (className) {  
    if(!this.className) return false;  
    return (this.className.search('(^|\\s)' + className + '(\\s|$)') != -1);  
   }

</script>
 </head>
 <body>
  <p><a class="test" onclick="alert(this.hasClass('test'));">Test</a></p>
 </b[/code]ody>
</html>

Gibt es da irgend eine Möglichkeit außer im onclick handler eine Clousure zu verwenden?

Jeena

  1. Hallo

    Vielleicht ist das folgende Nonsens, weil ich evtl. nicht ganz verstanden habe, was du meinst.

    Bei den anderen Sprachen musst du ja mit new eine neue Instanz erzeugen, in der du dann man $this auf sie selbst zeigst.

    In deinem Beispiel erzeugst du im onclick-Handler implizit auch ein neues Objekt, dass den A-Elementknoten abbildet.

    Also ist es richtig, dass this darauf verweist.

    Wie kann ich auf das aktuelle Objekt in JavaScript zugreifen? Mein Ansatz ist ja falsch, weil "this" beim definieren natürlich auf [Window Object] zeigt.

    In deinem Beispiel willst du ja offenbar genau das - oder habe ich das falsch verstanden?

    Gibt es da irgend eine Möglichkeit außer im onclick handler eine Clousure zu verwenden?

    Wo hast du da eine Closure? Eine Closure ist für mich das:

      
     function create() {  
      var privat=0;  
      var o={  
       methode:function() {  
        alert(privat);  
       }  
      };  
      return o;  
     }  
     a=create();  
     a.methode();  
    
    

    Wo die Variable 'privat' aus dem Kontext der Funktion 'create()' in der Methode 'methode()' eingeschlossen (closure) ist.

  2. gruss Jeena,

    ... Mein Ansatz ist ja falsch, weil "this" beim
    definieren natürlich auf [Window Object] zeigt.

    ... mitnichten ...

    Object.prototype.hasClass = function (className) {

    if(!this.className) return false;
        return (this.className.search('(^|\s)' + className + '(\s|$)') != -1);
       }

      
       ... den [this]-kontext betreffend ist Dein ansatz goldrichtig. ich wette,  
       dass Dein code, so wie Du Ihn hier gepostet hast, auch auf jeder gecko-  
       engine laeuft - vielleicht sogar im opera.  
      
       hast Du denn den code nicht auf zumindest einen browser losgelassen?  
      
       ich wuerde die erweiterung aber nicht an den prototypen von [Object]  
       nageln, denn dadurch kaeme wirklich jedes JavaScript-objekt, gewollt  
       oder nicht, in den genuss Deiner methode [hasClass].  
      
       ausserdem ist vor diesem hintergrund der methodenname missverstaendlich.  
       Du willst jedem knoten oder besser jedem element im dokumentenbaum eine  
       methode "hasClassName" oder "containsClassNames" mitgeben.  
      
       letztgesagtes direkt in JavaScript-code uebersetzt saehe dann so aus:  
      
       ~~~javascript
    Node.prototype.containsClassNames = function () {/* bzw.  
      
         HTMLElement.prototype.has...  
      
         [this] bezieht sich tatsaechlich auf alles,  
         was [Node]/[HTMLElement] ist oder auf alles,  
       was wie auch immer ueber den prototypen von  
       [Node]/[HTMLElement] geerbt hat.*/ /*  
      
          ... Dein code ...*/  
       };
    

    leider aber scheitert der von Dir gewaehlte loseungsansatz trotz seiner
       eleganz brutal an der praxis. die ueberwiegende mehrzahl der aktuellen
       browser-arten implementiert seine DOM-objekte NICHT als native JavaScript-
       objekte. die hersteller sind dazu auch nicht verpflichtet. ECMAScript 261
       beschreibt nur den JavaScript-sprachkern. DOM ist eine andere baustelle,
       und BOM traegt ein schweres erbe.

    wolltest Du nur spielen oder kann Deinem problem browseruebergreifend
       anderweitig abhilfe geschafft werden?

    by(t)e by(t)e - peterS. - pseliger@gmx.net

    --
    »Because objects in JavaScript are so flexible, you will want to think differently about class hierarchies.
    Deep hierarchies are inappropriate. Shallow hierarchies are efficient and expressive.« - Douglas Crockford
    ie:( fl:) br:> va:( ls:& fo:) rl:| n3;} n4:} ss:} de:µ js:} mo:? zu:]
    1. ... aehm ja ... huestel ... vertippt

      ... nicht verpflichtet. ECMAScript 261

      ECMAScript/ECMA-262

      beschreibt nur den JavaScript-sprachkern.

      so long - peterS. - pseliger@gmx.net

      --
      »Because objects in JavaScript are so flexible, you will want to think differently about class hierarchies.
      Deep hierarchies are inappropriate. Shallow hierarchies are efficient and expressive.« - Douglas Crockford
      ie:( fl:) br:> va:( ls:& fo:) rl:| n3;} n4:} ss:} de:µ js:} mo:? zu:]
    2. Hallo,

      Danke für deine Ausführungen.

      leider aber scheitert der von Dir gewaehlte loseungsansatz trotz seiner
         eleganz brutal an der praxis. die ueberwiegende mehrzahl der aktuellen
         browser-arten implementiert seine DOM-objekte NICHT als native JavaScript-
         objekte. die hersteller sind dazu auch nicht verpflichtet. ECMAScript 261
         beschreibt nur den JavaScript-sprachkern. DOM ist eine andere baustelle,
         und BOM traegt ein schweres erbe.

      Ok, ich verstehe, deshalb hat Safari auch unerwartete Ergebnisse geliefert. Der Firefox gibt tatsächlich das erwartete Ergebnis aus.

      wolltest Du nur spielen oder kann Deinem problem browseruebergreifend
         anderweitig abhilfe geschafft werden?

      Naja wie es halt immer so ist, erst einmal ein bischen herumspielen und wenn es läuft dann würde ich es mit anderen (addClassName, removeClassName) zusammenfassen und dann browserübergreifend nutzen wollen. Als Funktionen mit Übergabe des Objektes ist es ja ganz einfach aber wie du schon schriebst nicht wirklich so schön elegant.

      Jeena

  3. echo $begrüßung;

    In Python gibt es ja dieses "self" das sich immer auf das aktuelle Objekt bezieht:

    class JavaScriptObjects:

    def has_class(self, classname):
            return self.class_name == classname;

      
    Kleine Anmerkung: "self" ist eine Konvention, kein vom System vorgegebener Bezeichner. Die Referenz auf das aktuelle Objekt muss explizit als erster Parameter in der Funktiondefinition angegeben werden. Statt "self" kannst du auch irgendeinen anderen Namen verwenden. Sollte man aber nur machen, wenn man andere verwirren möchte.  
      
      
    echo "$verabschiedung $name";