schnack: Unterschied Objekt - Instanz

Hallo,
ich bin gerade dabei Javascript zu lernen und habe mich schon ein bisschen mit Objektorientierung befasst.
Nur bin ich noch nicht ganz dahinter gekommen, was der Unterschied zwischen einem Objekt und einer Instanz ist.
Kann mir da bitte einer helfen??
Danke im voraus,
schnack

  1. Hallo,
    ich bin gerade dabei Javascript zu lernen und habe mich schon ein bisschen mit Objektorientierung befasst.
    Nur bin ich noch nicht ganz dahinter gekommen, was der Unterschied zwischen einem Objekt und einer Instanz ist.

    Ach, diese ganzen Begriffe werden immer vermixxxt.
    Ich persönlich würde sagen, dass es genau dasselbe ist.
    Andere wiederum sagen, dass ein Objektes eine abstrakte Darstellung ist und eine Instanz eben eine konkrete Instanz eines Objektes ist.

    Z.B. ist ein "Vogel" ein Objekt und eine "Amsel A" eine konkrete Instanz.

    1. Z.B. ist ein "Vogel" ein Objekt und eine "Amsel A" eine konkrete Instanz.

      etwas weit hergeholt ausgedrückt ist eine klasse eine vorlage für eine werkzeugkiste, das werkzeug darin ist ein objekt bzw die funktion und die instanz der mechaniker der grade damit arbeitet

      beim instanzieren wird die werkzeugkiste gemäß vorlage bereitgestellt, jeder mechaniker kann sich also eine neue werkzeugkiste instanzieren ohne dass die ursprüngliche dadurch beeinträchtigt wird

      das ist der grosse unterschied zur prozeduralen verarbeitung, hier gibst nur eine werkzeugkiste und alle mechaniker arbeiten gleichzeitig damit - bei objektorientierter programmierung hat jeder mechaniker seine eigene kopie der kiste

      dass eine instanz ein objekt einer klasse ist, ist übrigens vermutlich eine fehlübersetzung - mir fällt spontan keine script/programmiersprache ein, in eine instanz NICHT eine ausprägung/exemplar einer klasse ist

      1. Hallo.

        bei objektorientierter programmierung hat jeder mechaniker seine eigene kopie der kiste

        Das wäre dumm und ist daher auch falsch. Eine Kopie verändert sich ja nicht, wenn sich das Original ändert.
        Ich persönlich hätte ja lieber zu einem Vergleich mit HTTP-Referenzen gegriffen.
        MfG, at

  2. Hallo,
    ich bin gerade dabei Javascript zu lernen und habe mich schon ein bisschen mit Objektorientierung befasst.
    Nur bin ich noch nicht ganz dahinter gekommen, was der Unterschied zwischen einem Objekt und einer Instanz ist.
    Kann mir da bitte einer helfen??
    Danke im voraus,
    schnack

    Da ist nicht so ganz klar. Häufig liest man dass die beiden Begriffe Synonyme sind in der OOP.

    Bei JavaScript ists dann noch schwieriger, da die Sprache nicht streng OO ist.

    Es gibt ja keine richtigen Klassen, und eigentlich ist alles ein Objekt. Auch Funktionen aus denen man wiederum Instanzen/Objekte erzeugen kann... alles klar?^^

    Gruß!

    1. gruss Christian S., hallo schnack,

      ich bin gerade dabei Javascript zu lernen und habe mich schon ein bisschen mit Objektorientierung befasst.
      Nur bin ich noch nicht ganz dahinter gekommen, was der Unterschied zwischen einem Objekt und einer Instanz ist.
      Kann mir da bitte einer helfen??
      Danke im voraus,
      schnack

      Da ist nicht so ganz klar. Häufig liest man dass die beiden Begriffe Synonyme sind in der OOP.
      Bei JavaScript ists dann noch schwieriger, ...

      ... da die Sprache nicht streng OO ist.

      @Christian

      wie kommst Du denn auf dieses schmale brett?

      welche programmierparadigmen muessen denn erfuellt sein,
      um einer bzw. Deiner definition von OO zu genuegen?
      was waere denn dann eine nicht strenge OO?

      Es gibt ja keine richtigen Klassen, ...

      es gibt auch keine falschen klassen, es gibt nicht mal
      ansatzweise etwas, das man so bezeichnen koennte.

      JavaScript ist klassenlos !

      ... und eigentlich ist alles ein Objekt.

      und uneigentlich? sei doch nicht so schwammig in der formulierung ;-)

      bis auf die typen [Undefined] und [Null] bzw. auf die primitiven
      werte "boolean", "number" und "string" finden sich im sprachkern
      nur noch objekte.

      @all

      mantra zur wissensauffrischung:

      der durch ECMA 262 standardiesierte sprachkern von JavaScript
      beschreibt eine multiparadigmensprache - JavaScript ist sowohl
      reine funktionale programmiersprache als auch sprache der OOP,
      denn sie erfuellt alle anforderungen, wie z.b. kapselung,
      vererbung und vielgestaltigkeit. zur abstraktion braucht es in
      der OO aber eben nicht immer klassen, diese laesst sich ohne
      weiteres auch mit prototypisch eingesetzten objekten abbilden.
      polymorphi (vielgestaltigkeit) ist eine weiter schon in die
      sprache eingebaute staerke von JavaScript - ob nun funktionale,
      objektorientierte oder parametrischer polymorphie ... alles kein
      problem. und nicht jeder ist gluecklich darueber das z.b. der "+"
      -operator (als bsp. fuer die polymorphie ueberladener operatoren)
      ueberladen ist. hervorzuheben ist aber die ebenfalls durch das
      sprachkonzept schon vorgegebene laufzeit-polymorphie (auch als
      spaetes bzw. dynamisches binden bezeichnet).

      das wars schon ... es geht aber noch mehr ...

      z.b. laesst sich allein mit den mitteln des sprachkerns fuer
      alle nativen JavaScript-objekte (d.h sowohl fuer instanzen von
      im sprachkern eingebauten objekten/konstruktorfunktionen als auch
      fuer instanzen selbstgeschriebener abstraktionen/konstruktoren)
      ein sauberes signal-slot-konzept (als spezielle auspraegung des
      beobeachter-entwurfsmusters) umsetzen, was ereignisgesteuertes
      programmieren (animationsbibliotheken oder kapselung von HTTP-
      requests/responses) unabhaengig von der DOM-API vereinfacht,
      ohne dabei so korumpierbar zu sein, wie z.b. die so haeufig
      eingesetzten callback-loesungen.

      sendungsbewusste gruesse - 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:]
      1. sendungsbewusste gruesse - so long - peterS. - pseliger@gmx.net

        <Geifernder Monolog>

        Ich vergleiche javascript mit jenem nostradamischen Geraune, dass man hin und wieder über Feindesland abwirft. Manchmal aber auch mit jenen fruchtlosen Gebeten zu Gott, die lediglich in der Intensität der Speichelproduktion variieren.
        Ideale Sprache kennt seinen Interpreter, Der Rest ist Babel.

        </Geifernder Monolog>

        mfg Beat

        --
        Selber klauen ist schöner!
      2. Hi,

        ... da die Sprache nicht streng OO ist.

        @Christian

        wie kommst Du denn auf dieses schmale brett?

        welche programmierparadigmen muessen denn erfuellt sein,
        um einer bzw. Deiner definition von OO zu genuegen?
        was waere denn dann eine nicht strenge OO?

        Ich meinte das im Sinne von:
        JS kennt keine access modifier (public, private, ...)
        JS kennt keine Klassen und keine Interfaces.
        JS ist nicht typisiert.
        Man kann JS auch prozedural schreiben.

        Und ich finde all das macht _strenge_ OO aus. Natürlich ist JS oo, aber halt nur halbherzig, imo.

        JavaScript ist klassenlos !

        dito.

        Gruß

        1. hallo again Christian,

          was waere denn dann eine nicht strenge OO?

          Ich meinte das im Sinne von:
          JS kennt keine access modifier (public, private, ...)

          die existenz bzw. nichtexistenz solcher modifier ist aber kein
          kriterium, um eine sprachen nach OO, streng OO bzw. nach nicht
          OO zu unterscheiden - kapselung, wofuer die von Dir genannten
          modifier in klassenbasierter OO stehen, ist in diesem fall das
          einzig ausschlaggebende kriterium fuer eine zuordnung.

          kapselung laesst sich in funktionalen (@ christoph: im zusammenhang
          mit JavaScript verzichte ich mal auf »rein«) programmierkonzepten
          ohne weiteres abbilden und in JavaScript z.b. so:

          gekapselte daten sind lokale werte bzw. objekte einer funktion.
          diese begrenzte *sichtbarkeit* von daten kann bei datenstrukturen
          durch ineinander verschachtelte funktionen (funktion in funktion)
          gezielt ausgenutzt und über referenzierungskonzepte ebenso gezielt
          getunnelt werden.

          JS kennt keine Klassen ...

          na und? - noch einmal ... in anderen worten:

          die implementierung bzw. das fehlen eines klassenkonzepts sagt ganau
          gar nichts darueber aus, ob eine sprache OO, streng OO, oder nicht OO
          ist - vererbung ist hier das entscheidende kriterium.

          ... und keine Interfaces.

          Du kennst JavaScript eben nicht richtig und schaust zusehr durch
          die brille der klassenbasierten OO. [apply] und [call] sind die
          beiden call-methoden, die dem konzept der interfaces in JavaScript
          rechnung tragen. zugleich sind es die beiden methoden, die den
          sex-appeal von JavaScript ausmachen, von klassenbasiert geschulten
          programmierern leider aber uebersehen werden, weil diese oftmals
          auf biegen und brechen versuchen, klassenbasierte vererbungskonzepte
          ueber aufgeblasene konstruktoren und deren [prototype]-eigenschaft
          in die sprachlandschaft hineinzuzimmern.

          JS ist nicht typisiert.

          dieses argument zaehlt ja nun mal gar nicht ;-) ... Smalltalk, die
          mutter aller modernen OO-sprachen ist ja nun mal reinrassig OO und
          dabei doch untypisiert  -  mantra: typisierung ist bei weitem kein
          kriterium, um eine sprache nach ..., ... und ... zu unterscheiden.

          Man kann JS auch prozedural schreiben.

          na und? ...

          • man kann in JavaScript sogar im 60er-stil rein imperativ, also
            komplett ohne kontrollstrukturen und ohne gegenseitige funktionsaufrufe,
            ja sogar ganz ohne funktionsrumpf schreiben.
          • man kann JavaScript-code aber auch funktional (@Christian: stilistisch
            auch _rein_ funktional) oder eben objektorientiert schreiben.

          Und ich finde all das macht _strenge_ OO aus.

          nein.

          Natürlich ist JS oo, ...

          na also,

          ... aber halt nur halbherzig, ...

          Du bist aber auch ein harter hund ;-)

          imo.

          • beschaeftige Dich bitte mit den grundlagen der informatik/programmierung.

          hier mal ein zweiter besser ausformulierter entwurf, der versucht,
          das sprachkonzept von JavaScript in aller kuerze zu beschreiben.

          » Der als ECMAScript (ECMA 262) standardisierte Sprachkern von JavaScript
            kann ohne weiteres als Multiparadigmensprache bezeichnet werden. Obwohl
            im Grunde eine funktionale Skriptsprache, läßt sich in JavaScript sowohl
            prozedural als auch rein funktional bzw. objektorientiert programmieren.

          In JavaScript representieren sich alle Daten bis auf die typen [Undefined]
            und [Null] bzw. bis auf die primitiven Werte [boolean], [number] und [string]
            als Objekte. Funktionen sind ebenfalls Objekte, deren im Funktionsrumpf
            gebundenen Anweisungen über den call-Operator bzw. über call-Methoden
            ausgeführt werden.

          Gekapselte Daten sind lokale Werte bzw. Objekte einer Funktion. Diese
            begrenzte *Sichtbarkeit* von Daten kann bei Datenstrukturen durch ineinander
            verschachtelte Funktionen (Funktion in Funktion) gezielt ausgenutzt und über
            Referenzierungskonzepte ebenso gezielt getunnelt werden.

          Schon auf dieser Grundlage läßt sich fuer alle nativen JavaScript-Objekte das
            Signal-Slot-Konzept implementieren, sodaß ereignisorientiertes Programmieren,
            auch losgelöst von DOM-Events, allein mit den Mitteln des Sprachkerns möglich
            ist.

          Vererbung wiederum erfolgt in JavaScript ausschließlich über Delegation;
            entweder direkt über eine der call-Methoden oder implizit über den Objekt-
            Prototypen eines jeden Objekt-Konstruktors. Letztgenannter leistet dabei
            die Abstraktion zur Vererbung (im Sinne von *ist ein*), während die zuerst
            angesprochenen Methoden der Umsetzung des Aggregationskonzepts (*hat ein*)
            dienlich sind.«

          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:]
      3. Moin.

        Es gibt ja keine richtigen Klassen, ...

        es gibt auch keine falschen klassen, es gibt nicht mal
        ansatzweise etwas, das man so bezeichnen koennte.

        JavaScript ist klassenlos !

        Richtig, JavaScript unterstützt prototypische Vererbung. Allerdings in einer meiner Meinung nach extrem schwachsinnigen Form über constructor.prototpe - ein direkter Zugriff auf [[Prototype]] ist nicht möglich. Statt dessen wird man zu pseudo-klassenbasierter Programmierung gezwungen. Allerdings ist JavaScript mächtig genug, um dieses Situation mit wenigen Zeilen Code (meine Version) in Ordnung zu bringen...

        der durch ECMA 262 standardiesierte sprachkern von JavaScript
        beschreibt eine multiparadigmensprache - JavaScript ist sowohl
        reine funktionale programmiersprache

        Nein, nicht wirklich.

        als auch sprache der OOP,
        denn sie erfuellt alle anforderungen, wie z.b. kapselung,
        vererbung und vielgestaltigkeit.

        Wobei es für nicht jedes dieser Konzepte 'syntactic sugar' gibt. Das ist aber gerade der Punkt: Objekt-ortientiert kann man auch in C progammieren (ist auch nicht wirklich kompliziert), trotzdem würde niemand C als OO-Sprache bezeichnen...

        Christoph

        1. gruss Christoph,

          JavaScript ist klassenlos !

          Richtig, JavaScript unterstützt prototypische Vererbung. Allerdings in einer
          meiner Meinung nach extrem schwachsinnigen Form über constructor.prototpe -

          dafuer kann ich nichts - das steht hier aber auch nicht zur debatte.

          ein direkter Zugriff auf [[Prototype]] ist nicht möglich. Statt dessen wird
          man zu pseudo - klassenbasierter Programmierung gezwungen.

          aber doch nur, wenn man seine klassenbasierte denke nicht ablegen kann.

          man kann aeusserst effizient programmieren, wenn man sich gar nicht erst
          auf die von »constructor.prototpe« als fata morgana unscharf am horizont
          versprochene emulation einer klassenbasierenden vererbung einlaesst.

          ... man bleibe in seiner komoden funktionalen oase und preise deren
              immerfrischen quellen [apply] und [call].

          im ernst, »constructor.prototpe« findet seine einzig sinnvolle und dann auch
          effektive anwendung im hinzufuegen von (oeffentlichen) prototypischen methoden.
          mehr braucht es auch nicht.

          Allerdings ist JavaScript mächtig genug, um dieses Situation mit wenigen
          Zeilen Code (meine Version) in Ordnung zu bringen...

          sauber gemacht, und fuer die klassendenke genau richtig. ich verschliesse
          mich dieser konzeption in den wenigen faellen, in denen sie effektiver ist
          auch ueberhaupt nicht.

          zum spass und zur veranschaulichung hab ich Dein beispiel aber mal so
          hingebogen, dass es nur auf objekten aufbaut. normalerweise wuerde man
          das aber auf zwei bis drei objekte eindampfen. Dein bsp. ist aus sicht
          der klassenbasierten OO gut gewaehlt - meine vergewaltigung Deiner
          *pseudoklassen*-konstruktoren zu objekten ist natuerlich voellig an
          der praxis vorbei - trotzdem kann ich Deinen hund zum schluss ganz
          einfach auch miauen lassen, im kontext von [strangeDog] macht [killer]
          dann noch ganz andere sachen:

          [code lang = javascript]var animal = {

          makeSound : (function(sound) {

          return (sound || this.sound || animal.sound);
            }),
            sound : "grmpf"
          };

          var dog = {

          sound : "Wuf"
          };

          var myDog = {

          bark : (function(sound) {

          alert(this.owner + "'s dog " + this.name + " says " + animal.makeSound.call(this, (sound || dog.sound)));
            }),
            owner: "unknown",
            name: "unknown"
          };
          var strangeDog = {

          bark : (function(sound) {

          alert(this.owner + "'s dog " + this.name + " says " + animal.makeSound.call(this, sound));
            })
          };

          var killer = {

          name: "Killer",
            owner: "cygx"
          };

          myDog.bark.call(killer);         // "Wuf"
          myDog.bark.call(killer, "meow"); // "meow"

          strangeDog.bark.call(killer, "quak"); // "quak"
          strangeDog.bark.call(killer);         // "grmpf"[/code]

          der durch ECMA 262 standardiesierte sprachkern von JavaScript
          beschreibt eine multiparadigmensprache - JavaScript ist sowohl
          reine funktionale programmiersprache

          Nein, nicht wirklich.

          meinetwegen - dann formuliere ich praeziser (siehe auch mein
          zweiter sprachdefinitionsveruch in meiner antwort an Christian):

          » ... Obwohl im Grunde eine funktionale Skriptsprache, läßt sich in JavaScript
            sowohl prozedural als auch rein funktional bzw. objektorientiert programmieren.«

          als auch sprache der OOP, denn sie erfuellt alle anforderungen,
          wie z.b. kapselung, vererbung und vielgestaltigkeit.

          Wobei es für nicht jedes dieser Konzepte 'syntactic sugar' gibt.

          muss es ja auch nicht - da kommt die grosse flexibilitaet eines funktionalen
          sprachkonzepts zum tragen.

          Das ist aber gerade der Punkt: Objekt - ortientiert kann man auch in C progammieren
          (ist auch nicht wirklich kompliziert), trotzdem würde niemand C als OO-Sprache bezeichnen...

          uuh, das bsp. ist boes' gewaehlt - gerade C und seine abkoemmlinge mit seinem/deren
          so langem evolutionaeren entwicklungsweg ins feld zu fuehren ist schamlos gemein ;-)

          C++ wuerde ich aber schon als objektorientiert bezeichnen, obwohl es ja auch mehreren
          programmierparadigmen genuegt.

          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:]
          1. Moin.

            Vielleicht nur noch mal zur Verdeutlichung meines Standpunkts: Aus klassischen OO-Sprachen (egal, ob prototypisch oder klassenbasiert) ist man es gewohnt, eine komplexe Vererbungshierarchie aufzubauen. In JavaScript tut man (zumindest ich ;)) das in der Regel nicht. Daher ist JavaScript keine klassische OO-Sprache.

            Weiterhin wird man in JavaScript nicht dazu gezwungen, objektorientiert zu Programmieren. Also ist es keine reine OO-Sprache, obwohl Objekte ein integraler Bestandteil des Sprachkerns sind.

            man kann aeusserst effizient programmieren, wenn man sich gar nicht erst
            auf die von »constructor.prototpe« als fata morgana unscharf am horizont
            versprochene emulation einer klassenbasierenden vererbung einlaesst.

            ... man bleibe in seiner komoden funktionalen oase und preise deren
                immerfrischen quellen [apply] und [call].

            Aber dieser Programmierstil ist dann nicht mehr OO, da Daten und Funktionalität nicht in einem Paket zusammengefasst werden, sondern Funktionalität aus beliebiger Quelle nach gutdünken hinzugemischt wird. Was zugegebenermaßen ziemlich praktisch ist (habe ich bereits erwähnt, dass ich JavaScript - trotz aller Ecken und Kanten - mag?).

            Über die genaue Klassifikation der Sprache Java/ECMA-Script lässt sich sicherlich noch herrlich, aber letztlich sinnlos weiterdiskutieren. Aber hey, solange man Spaß daran hat und dank Bänderriss auch keine andere Freizeitbeschäftigung, stehe ich dazu gerne weiter zur Verfügung ;)

            Christoph

            PS:

            C++ wuerde ich aber schon als objektorientiert bezeichnen, obwohl es ja auch mehreren
            programmierparadigmen genuegt.

            I invented the term Object-Oriented, and I can tell you I did not have C++ in mind. (Alan Kay)

            1. hallo again Christoph,

              Vielleicht nur noch mal zur Verdeutlichung meines Standpunkts: Aus klassischen
              OO-Sprachen (egal, ob prototypisch oder klassenbasiert) ...

              was waeren denn das fuer sprachen - zumindest in der prototypenfraktion laesst
              sich doch nur »Self« zum vergleich heranziehen. in den klassenbasierten sprachen
              bin ich nicht so bewandert, kenne mich eigentlich nur mit »JAVA« aus und wuesste
              auch nicht, welche sprache(n) dort als *klassisch* bezeichnet werden koennte(n) -
              vielleicht ja doch wieder C++ ?;-)

              ... ist man es gewohnt, eine komplexe Vererbungshierarchie aufzubauen. In
              JavaScript tut man (zumindest ich ;)) das in der Regel nicht. Daher ist
              JavaScript keine klassische OO-Sprache.

              au backe ... , ... wie die durch eine sprache zur verfuegung gestellten konzepte
              schlussendlich genutzt werden, steht und faellt doch zuallerersteinmal mit dem
              anwendungs(um)feld, der art der dortigen problemstellungen und deren moeglicher
              komplexitaet sowie der grundsaetzlichen loesbarkeit einer aufgabe innerhalb der
              vorhandenen rahmenbedingungen.

              und wenn ich Deiner argumentation folgte, und »Self« als klassisch klassenlose
              OO-sprache heranzoege, zerfiele doch das argument komplexer vererbungshierarchien
              als kriterium klassischer 00-sprachen gleich wieder.

              Weiterhin wird man in JavaScript nicht dazu gezwungen, objektorientiert zu
              Programmieren. Also ist es keine reine OO-Sprache, obwohl Objekte ein integraler
              Bestandteil des Sprachkerns sind.

              in welchen sprachen der OOP wird man denn dazu gezwungen 00 zu programmieren?
              und dass mein ich nicht als theoretischen scheingegenargument. OO ist eine denke,
              ein geistiger werkzeugkasten, um komplexe probleme moeglichst effizient zu loesen.
              jede sprache, die es mir ermoeglicht, aufgaben auf dem wege der OOP zu loesen,
              darf auch als sprache der OO bezeichnet werden.

              und wenn eine sprache auch noch anderen programmierparadigmen genuegt, disqualifiziert
              sie dies dann natuerlich fuer das brustschildchen *_reine_ objektorientierte sprache*.

              was bleibt dann aber zur etikettierung noch uebrig? - »Smalltalk«? ...

              ... ich weis es nicht, und ich finde es ebenfalls muessig, soetwas auszudiskutieren.
              aber wenn man dies fuer eine sprache - wie hier zum bsp. fuer JavaScript - tut, dann
              sollten die argumente schon stichhaltiger sein.

              man kann aeusserst effizient programmieren, wenn man sich gar nicht erst
              auf die von »constructor.prototpe« als fata morgana unscharf am horizont
              versprochene emulation einer klassenbasierenden vererbung einlaesst.

              ... man bleibe in seiner komoden funktionalen oase und preise deren
                  immerfrischen quellen [apply] und [call].

              Aber dieser Programmierstil ist dann nicht mehr OO, da Daten und Funktionalität
              nicht in einem Paket zusammengefasst werden, sondern Funktionalität aus beliebiger
              Quelle nach gutdünken hinzugemischt wird. ...

              was ist an schnittstellenvererbung und objektkomposition nicht OO?

              »Die am häufigsten mißverstandene Programmiersprache der Welt« - zitat aus dem nachwort:

              » Zwei Leitsätze der "Gang of Four" für den erfolgreichen Einsatz von Entwurfsmustern
                lauten: "Programmiere auf eine Schnittstelle hin, nicht auf eine Implementierung."
                (klassenbasierte vs. Schnittstellen-Vererbung) und "Ziehe Objektkomposition der
                Klassenvererbung vor." (Vererbung vs. Komposition) - JavaScript unterstützt diese
                Programmierparadigmen.«

              ... Was zugegebenermaßen ziemlich praktisch ist ...

              na also - es ist sogar richtig sexy

              (habe ich bereits erwähnt, dass ich JavaScript - trotz aller Ecken und Kanten - mag?).

              ... ich hab' dich auch lieb ...

              Über die genaue Klassifikation der Sprache Java/ECMA-Script lässt sich sicherlich
              noch herrlich, aber letztlich sinnlos weiterdiskutieren. Aber hey, solange man Spaß
              daran hat und dank Bänderriss auch keine andere Freizeitbeschäftigung, stehe ich dazu
              gerne weiter zur Verfügung ;)

              ... ach noe lass mal - wie gefaellt Dir denn »Ruby«s vererbungskonzept so?...  ;-)

              ps

              Über die genaue Klassifikation der Sprache Java/ECMA-Script lässt sich sicherlich
              noch herrlich, aber letztlich sinnlos weiterdiskutieren.

              ich denke wirklich, dass die Formulierung am ende dieses postings sehr belastbar ist.

              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:]
              1. Moin.

                was waeren denn das fuer sprachen - zumindest in der prototypenfraktion laesst
                sich doch nur »Self« zum vergleich heranziehen. in den klassenbasierten sprachen
                bin ich nicht so bewandert, kenne mich eigentlich nur mit »JAVA« aus und wuesste
                auch nicht, welche sprache(n) dort als *klassisch* bezeichnet werden koennte(n) -
                vielleicht ja doch wieder C++ ?;-)

                Klassen-basiert z.B. Smalltalk, Simula 87, Java/C#, C++ ;)
                Prototypisch z.B. Self, Io, Lisaac(?)

                ... ist man es gewohnt, eine komplexe Vererbungshierarchie aufzubauen. In
                JavaScript tut man (zumindest ich ;)) das in der Regel nicht. Daher ist
                JavaScript keine klassische OO-Sprache.

                au backe ... , ... wie die durch eine sprache zur verfuegung gestellten konzepte
                schlussendlich genutzt werden, steht und faellt doch zuallerersteinmal mit dem
                anwendungs(um)feld, der art der dortigen problemstellungen und deren moeglicher
                komplexitaet sowie der grundsaetzlichen loesbarkeit einer aufgabe innerhalb der
                vorhandenen rahmenbedingungen.

                Wie baut man denn in JavaScript *nur mit Bordmitteln* Vererbungs_hierarchien_?

                und wenn ich Deiner argumentation folgte, und »Self« als klassisch klassenlose
                OO-sprache heranzoege, zerfiele doch das argument komplexer vererbungshierarchien
                als kriterium klassischer 00-sprachen gleich wieder.

                In Self ist es einfach möglich, eine Vererbungshierarchie mit Tiefen > 1 zu bauen, in JavaScript nicht.

                Weiterhin wird man in JavaScript nicht dazu gezwungen, objektorientiert zu
                Programmieren. Also ist es keine reine OO-Sprache, obwohl Objekte ein integraler
                Bestandteil des Sprachkerns sind.

                in welchen sprachen der OOP wird man denn dazu gezwungen 00 zu programmieren?
                und dass mein ich nicht als theoretischen scheingegenargument. OO ist eine denke,
                ein geistiger werkzeugkasten, um komplexe probleme moeglichst effizient zu loesen.
                jede sprache, die es mir ermoeglicht, aufgaben auf dem wege der OOP zu loesen,
                darf auch als sprache der OO bezeichnet werden.

                Also ist laut deinen Aussagen C eine OO-Sprache. Gewagt.

                und wenn eine sprache auch noch anderen programmierparadigmen genuegt, disqualifiziert
                sie dies dann natuerlich fuer das brustschildchen *_reine_ objektorientierte sprache*.

                Definitionssache. Für mich ist eine Multiparadigmen-Sprache keine reine OO-Sprache, genausowenig, wie bereits Scheme keine rein funktionale Sprache im eigentlichen Sinn ist (vergleiche die Links meines vorletzten(?) Posts).

                was bleibt dann aber zur etikettierung noch uebrig? - »Smalltalk«? ...

                Richtig.

                ... ich weis es nicht, und ich finde es ebenfalls muessig, soetwas auszudiskutieren.
                aber wenn man dies fuer eine sprache - wie hier zum bsp. fuer JavaScript - tut, dann
                sollten die argumente schon stichhaltiger sein.

                Ich halte meine Argumentation durchaus für stichhaltig ;)

                man kann aeusserst effizient programmieren, wenn man sich gar nicht erst
                auf die von »constructor.prototpe« als fata morgana unscharf am horizont
                versprochene emulation einer klassenbasierenden vererbung einlaesst.

                ... man bleibe in seiner komoden funktionalen oase und preise deren
                    immerfrischen quellen [apply] und [call].

                Aber dieser Programmierstil ist dann nicht mehr OO, da Daten und Funktionalität
                nicht in einem Paket zusammengefasst werden, sondern Funktionalität aus beliebiger
                Quelle nach gutdünken hinzugemischt wird. ...

                was ist an schnittstellenvererbung und objektkomposition nicht OO?

                Vielleicht habe ich nur noch nicht herausgefunden, wie man in JavaScript objektorientiert programmiert? Meinst du mit Schnittstellenprogrammierung/Objektkomposition, dass man sich zunächst ein Schnittstellen-Objekt mit geeigneten Methoden baut und diese dann jedem Objekt, dass dies Schnittstelle implementiert, (bzw. dem Prototyp dessen Konstruktors) hinzufügt? Das wäre eine Möglichkeit, objektorientiert in JavaScript zu Programmieren (ich arbeite in der Regel nicht so).
                Allerdings bietet JavaScript keine syntaktische Unterstützung für diesen Programmierstil (was sich natürlich problemlos in 3 Zeilen Code beheben lässt), aber damit wären wir wieder beim Argument, dass auch in C objektorientiert programmiert werden kann, nur halt ohne nette Syntax.

                In meinen Augen sind nur die folgenden Alternativen konsistent:
                  1. C ist keine OO-Sprache, JavaScript ist OO-Sprache (aber weder eine reine noch eine klassische)
                  2. C ist OO-Sprache, JavaScript ist reine OO-Sprache

                Ich tendiere stark zu 1.

                [...]

                (habe ich bereits erwähnt, dass ich JavaScript - trotz aller Ecken und Kanten - mag?).

                ... ich hab' dich auch lieb ...

                Na jetzt kann ich wieder beruhigt schlafen ;)

                Über die genaue Klassifikation der Sprache Java/ECMA-Script lässt sich sicherlich
                noch herrlich, aber letztlich sinnlos weiterdiskutieren. Aber hey, solange man Spaß
                daran hat und dank Bänderriss auch keine andere Freizeitbeschäftigung, stehe ich dazu
                gerne weiter zur Verfügung ;)

                ... ach noe lass mal - wie gefaellt Dir denn »Ruby«s vererbungskonzept so?...  ;-)

                Keine Ahnung, ich habe noch nie in Ruby programmiert. Aber man munkelt, es handle sich um eine ver-perl-ten Bastard von Smalltalk.

                Christoph

                1. gruss Christoph,

                  Wie baut man denn in JavaScript *nur mit Bordmitteln* Vererbungs_hierarchien_?

                  so wie bereits im meinereinigen definitionsversuch beschrieben:

                  » Vererbung wiederum erfolgt in JavaScript ausschließlich über Delegation;
                    entweder direkt über eine der call-Methoden oder implizit über den Objekt-
                    Prototypen eines jeden Objekt-Konstruktors. Letztgenannter leistet dabei
                    die Abstraktion zur Vererbung (im Sinne von *ist ein*), während die zuerst
                    angesprochenen Methoden der Umsetzung des Aggregationskonzepts (*hat ein*)
                    dienlich sind.«

                  In Self ist es einfach möglich, eine Vererbungshierarchie mit Tiefen > 1 zu bauen,
                  in JavaScript nicht.

                  warum denn nicht, dafuer kann man doch jedem konstruktor ein prototypisches
                  objekt zur seite stellen - das von Dir kritisierte *constructor.prototype*.

                  hier mal ein beispiel, welches eine prototypische vererbungskette ueber folgende
                  konstruktoren aubaut: [[Mamal]] --> [[CanisLupus]] --> [[CanisCanis]], wobei eine
                  instanz von [[Mamal]] der prototyp von [[CanisLupus]] ist, und ein [CanisLupus]-
                  objekt wiederum den prototypen von [[CanisCanis]] stellt.

                  die saueger-abstraktion stellt die atmung bereit. die wolfs-abstraktion erbt
                  die atmung von einem saeuger-objekt und stellt sicher, dass reviere markiert
                  werden koennen. die hunde-abstraktion wiederum erbt von einer wolfs-instanz
                  und will ein potentielles herrchen mit stoeckchenholen gluecklich machen.

                  ausserdem gibt es noch ausgabefunktionalitaet, die in keinen der genannten
                  konstruktoren nativ eingebaut ist. damit diese aber trotzdem jedem objekt
                  zur verfuegung steht und nicht frei herumschwebt, wird sie in eine art
                  interface verpackt, welches einmalig von [[Mamal]] implementiert wird.

                  den beispielcode lasse man dann bitte durch copy und paste auf die jconsole los:

                  var OutputInterface = (function () {  
                    
                    
                   var constr;  
                    
                   if (typeof print == "function") {  
                    
                    constr = (function () {  
                    
                     this.trace = (function (str) {  
                    
                      print(str);  
                     });  
                    });  
                    
                   } else {  
                    
                    constr = (function () {  
                    
                     this.trace = (function (str) {  
                    
                      document.title = str;  
                     });  
                    });  
                   }  
                    
                   return constr;  
                    
                  })();  
                    
                    
                  var Mamal = (function () {  
                    
                    
                   OutputInterface.call(this);  
                    
                    
                   var timeoutIdBreathing;  
                   var self = this;  
                    
                   var breathIn = (function () {  
                    
                    clearTimeout(timeoutIdBreathing);/*  
                    
                    document.title = "... breath in ...";  
                    if (print) {print("... breath in ...");}*/  
                    self.trace("... breath in ...");  
                    
                    timeoutIdBreathing = setTimeout(breathOut, 1500);  
                   });  
                   var breathOut = (function () {  
                    
                    clearTimeout(timeoutIdBreathing);/*  
                    
                    document.title = "... breath out ...";  
                    if (print) {print("... breath out ...");}*/  
                    self.trace("... breath out ...");  
                    
                    timeoutIdBreathing = setTimeout(breathIn, 1500);  
                   });  
                    
                    
                   this.justBreath = (function () {  
                    
                    breathIn();  
                   });  
                   this.holdBreath = (function () {  
                    
                    clearTimeout(timeoutIdBreathing);/*  
                    
                    document.title = "... breathing on hold ...";  
                    if (print) {print("... breathing on hold ...");}*/  
                    self.trace("... breathing on hold ...");  
                   });  
                    
                    
                   breathIn();  
                    
                  });/*  
                    
                    
                  var myMamal = new Mamal;*/  
                    
                    
                  var CanisLupus = (function () {  
                    
                    
                   var constr = (function () {  
                    
                    
                    var timeoutIdMarking;  
                    var self = this;  
                    
                    var markingTerritory = (function () {  
                    
                     clearTimeout(timeoutIdMarking);/*  
                    
                     document.title = "... marking territory !..";  
                     if (print) {print("... marking territory !..");}*/  
                     self.trace("... marking territory !..");  
                    
                     timeoutIdMarking = setTimeout(markingTerritory, 10500);  
                    });  
                    
                    
                    this.goingToMarkTerritory = (function () {  
                    
                     markingTerritory();  
                    });  
                    this.stopMarkingTerritory = (function () {  
                    
                     clearTimeout(timeoutIdMarking);/*  
                    
                     document.title = "... marking territory stopped ...";  
                     if (print) {print("... marking territory stopped ...");}*/  
                     self.trace("... marking territory stopped ...");  
                    });  
                   });  
                   constr.prototype = new Mamal;  
                    
                   constr.prototype.holdBreath();  
                    
                    
                   return constr;  
                    
                  })();/*  
                    
                    
                  var myWolf = new CanisLupus;  
                    
                    
                  setTimeout(myWolf.justBreath, 5000);  
                  setTimeout(myWolf.holdBreath, 60000);  
                    
                  setTimeout(myWolf.goingToMarkTerritory, 1000);  
                  setTimeout(myWolf.stopMarkingTerritory, 51500);\*/  
                    
                    
                  var CanisCanis = (function () {  
                    
                    
                   var constr = (function () {  
                    
                    
                    var timeoutIdRetrieving;  
                    var self = this;  
                    
                    var goGetIt = (function () {  
                    
                     clearTimeout(timeoutIdRetrieving);/*  
                    
                     document.title = "... run and jump for stick ...";  
                     if (print) {print("... run and jump for stick ...");}*/  
                     self.trace("... run and jump for stick ...");  
                    
                     timeoutIdRetrieving = setTimeout(goGetIt, 13300);  
                    });  
                    
                    
                    this.goingToRetrieveStick = (function () {  
                    
                     goGetIt();  
                    });  
                    this.stopRetrievingStick = (function () {  
                    
                     clearTimeout(timeoutIdRetrieving);/*  
                    
                     document.title = "... retrieving stopped ...";  
                     if (print) {print("... retrieving stopped ...");}*/  
                     self.trace("... retrieving stopped ...");  
                    });  
                   });  
                   constr.prototype = new CanisLupus;  
                    
                    
                   return constr;  
                    
                  })();  
                    
                    
                  var myDog = new CanisCanis;  
                    
                    
                  setTimeout(myDog.justBreath, 5000);  
                  setTimeout(myDog.holdBreath, 60000);  
                    
                  setTimeout(myDog.goingToMarkTerritory, 1000);  
                  setTimeout(myDog.stopMarkingTerritory, 51500);  
                    
                  setTimeout(myDog.goingToRetrieveStick, 1500);  
                  setTimeout(myDog.stopRetrievingStick, 53600);
                  

                  im uebrigen laesst sich in JavaScript sogar mehrfachvererbung abbilden.

                  in welchen sprachen der OOP wird man denn dazu gezwungen 00 zu programmieren?
                  und dass mein ich nicht als theoretischen scheingegenargument. OO ist eine denke,
                  ein geistiger werkzeugkasten, um komplexe probleme moeglichst effizient zu loesen.
                  jede sprache, die es mir ermoeglicht, aufgaben auf dem wege der OOP zu loesen,
                  darf auch als sprache der OO bezeichnet werden.

                  Also ist laut deinen Aussagen C eine OO-Sprache. Gewagt.

                  ich weiss, aber meine intension dahinter ist doch offensichtlich, ... wahrnehmungsbrillen
                  fuer das sprachkonzept von JavaScript zu verteilen.

                  was ist an schnittstellenvererbung und objektkomposition nicht OO?

                  Vielleicht habe ich nur noch nicht herausgefunden, wie man in JavaScript objektorientiert
                  programmiert? Meinst du mit Schnittstellenprogrammierung/Objektkomposition, dass man sich
                  zunächst ein Schnittstellen-Objekt mit geeigneten Methoden baut und diese dann jedem Objekt,
                  dass dies Schnittstelle implementiert, (bzw. dem Prototyp dessen Konstruktors) hinzufügt?

                  ja, aber einen konstruktor in seinem einsatz so umzubiegen, dass er dem konzept der interfaces
                  genuegt, ist nur eine der moeglichkeiten. delegation ist, wie schon gezeigt, auch auf direktem
                  weg ueber [call] und [apply] - und das nicht nur auf reiner objektbasis - moeglich.

                  Allerdings bietet JavaScript keine syntaktische Unterstützung für diesen Programmierstil ...

                  doch, das obige bsp. sollte das gegenteil beweisen.

                  ... (was sich natürlich problemlos in 3 Zeilen Code beheben lässt), aber damit wären wir
                  wieder beim Argument, dass auch in C objektorientiert programmiert werden kann, nur halt
                  ohne nette Syntax.

                  die nette syntax zaehlt aber nicht als argument ;-)

                  In meinen Augen sind nur die folgenden Alternativen konsistent:
                    1. C ist keine OO-Sprache, JavaScript ist OO-Sprache (aber weder eine reine noch eine klassische)
                    2. C ist OO-Sprache, JavaScript ist reine OO-Sprache

                  Ich tendiere stark zu 1.

                  fuer 1) breche ich hier doch die ganze zeit immer wieder eine neue lanze.

                  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:]
                  1. Moin.

                    In Self ist es einfach möglich, eine Vererbungshierarchie mit Tiefen > 1 zu bauen,
                    in JavaScript nicht.

                    warum denn nicht, dafuer kann man doch jedem konstruktor ein prototypisches
                    objekt zur seite stellen - das von Dir kritisierte *constructor.prototype*.

                    Entschuldige bitte, aber dass, was du als Beispiel ablieferst, überzeugt mich nur noch mehr von meinem Standpunkt, da du hier Funktionalität über Closures nachbauen musst, für die die Sprache keine syntaktische Unterstützung liefert. Ich habe die für die Vererbung relevanten Teile deines Codes mal für mich verständlich aufgedröselt:

                      
                    function Ancestor() {  
                     this.ancestorProp = 1;  
                    }  
                    Ancestor.prototype.ancestorProtoProp = 1;  
                      
                    var Instance = (function() {  
                     function Constructor() {  
                      this.instanceProp = 1;  
                     }  
                     Constructor.prototype = new Ancestor;  
                     Constructor.prototype.instanceProtoProp = 1;  
                     return Constructor;  
                    })();  
                    
                    

                    Das funktioniert, hat aber den Nachteil, dass der Konstruktor Ancestor während der Definition von Instance und nicht bei der Instanziierung über new Instance ausgeführt wird. Daher bevorzuge ich folgende Variante:

                      
                    Function.prototype.extend = function(ancestor) {  
                     function Prototype() {}  
                     Prototype.prototype = ancestor.prototype;  
                     this.prototype = new Prototype();  
                     return this;  
                    };  
                      
                    function Ancestor() {  
                     this.ancestorProperty = 1;  
                    }  
                    Ancestor.prototype.ancestorProtoProperty = 1;  
                      
                    function Instance() {  
                     Ancestor.call(this);  
                     this.instanceProperty = 1;  
                    }  
                    Instance.extend(Ancestor);  
                    Instance.prototype.instanceProtoProperty = 1;  
                    
                    

                    Allerdings bietet JavaScript keine syntaktische Unterstützung für diesen Programmierstil ...

                    doch, das obige bsp. sollte das gegenteil beweisen.

                    Das würde ich nicht als syntaktische Unterstüzung bezeichnen, sondern als Workaround...

                    ... (was sich natürlich problemlos in 3 Zeilen Code beheben lässt), aber damit wären wir
                    wieder beim Argument, dass auch in C objektorientiert programmiert werden kann, nur halt
                    ohne nette Syntax.

                    die nette syntax zaehlt aber nicht als argument ;-)

                    Doch. Sie ist das _einzige_ Argument, dass zählt, da sich in (fast) jeder Sprache objektorientiert programmieren lässt!

                    In meinen Augen sind nur die folgenden Alternativen konsistent:
                      1. C ist keine OO-Sprache, JavaScript ist OO-Sprache (aber weder eine reine noch eine klassische)
                      2. C ist OO-Sprache, JavaScript ist reine OO-Sprache

                    Ich tendiere stark zu 1.

                    fuer 1) breche ich hier doch die ganze zeit immer wieder eine neue lanze.

                    Na dann sind wir uns ja eigentlich einig ;)

                    Christoph

                    1. [...] da du hier Funktionalität über Closures nachbauen musst, für die die Sprache keine syntaktische Unterstützung liefert [...]

                      Streich das 'über Closures', die äußere Funktion dient nur zur Kapselung des Namensraums...

                      Christoph

                    2. gruss Christoph,

                      Entschuldige bitte, aber dass, was du als Beispiel ablieferst, überzeugt
                      mich nur noch mehr von meinem Standpunkt, da du hier Funktionalität ...
                      (gestrichen) ... nachbauen musst, für die die Sprache keine syntaktische
                      Unterstützung liefert. ...

                      aber gerade diese flexibilitaet, *syntactic sugar*, wie Du es nennst,
                      jederzeit nachreichen zu koennen, macht doch das sprachkonzept so stark.

                      was Du vermisst, baust Du nach - natuerlich muss man absolut sattelfest
                      darin sein, wie [[Function]], [call], [apply], und [prototype] wirken,
                      bevor man, auf diesen grundkonzepten aufbauend, daran gehen kann, auch
                      noch damit zu zaubern.

                      ... Ich habe die für die Vererbung relevanten Teile deines Codes mal
                      für mich verständlich aufgedröselt:

                      ... code ...

                      Das funktioniert, hat aber den Nachteil, dass der Konstruktor Ancestor
                      während der Definition von Instance und nicht bei der Instanziierung
                      über new Instance ausgeführt wird. Daher bevorzuge ich folgende Variante:

                      Function.prototype.extend = function(ancestor) {/*
                        ... code ...
                      */
                      };

                      ... noch mehr code ...

                      ja, ich mach das doch auch so, weil es sich in der anwendung schlussendlich
                      besser lesen laesst - genausogut liesse sich auch noch ein ...

                      Function.prototype.implements = function(interface/*:Function*/) {/*  
                        ... code ...  
                        */  
                      };
                      

                      ... schreiben. das von mir gegebene bsp. sollte doch nur schulmaessig die
                      prinzipielle machbarkeit zeigen, da auf diesem mit bordmitteln beschrittenen
                      weg die konzeption sichtbar bleibt und eben nicht hinter einer fassade versteckt
                      wird.

                      doch, das obige bsp. sollte das gegenteil beweisen.

                      Das würde ich nicht als syntaktische Unterstüzung bezeichnen, sondern als Workaround...

                      ...

                      die nette syntax zaehlt aber nicht als argument ;-)

                      Doch. Sie ist das _einzige_ Argument, dass zählt, da sich in (fast) jeder Sprache
                      objektorientiert programmieren lässt !

                      mhh ... darueber muessen wir das kriegsbeil begraben.

                      ich mag nun mal puristisch ausgestattete werkzeugkaesten und friemelige handarbeit.

                      fuer 1) breche ich hier doch die ganze zeit immer wieder eine neue lanze.

                      Na dann sind wir uns ja eigentlich einig ; )

                      eben.

                      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. ups ... entschuldigung ... ganz viele typos:

                    »breathe in« / »breathe out« anstatt »breath in« / »breath out« und
                    »breatheIn« / »breatheOut« an stelle von »breathIn« / »breathOut«.

                    ... und ja der »Canis Canis« heisst korrekterweise »Canis lupus familiaris«,
                    und das in zweierlei hinsicht verunglueckte  »Mamal« ist ein englisches
                    »Mammal« und wird im latainischen mit der pluralform »Mammalia« bezeichnet ...

                    ... war halt sehr spaet bzw. zu frueh, um sich vernuenftig zu konzentrieren -
                    dafuer laeuft aber wenigstens das code-beispiel ohne zicken durch.

                    so long - peterS.

                    1. Moin.

                      ups ... entschuldigung ... ganz viele typos:

                      Es sei dir entschuldigt. In meiner Antwort ist auch mindestens ein 's' zu viel ;)

                      Christoph

      4. Hallo.

        JavaScript ist klassenlos !

        JnternationaleSolidarität.
        MfG, at