'Klassen' und Events pro 'Instanz'
Jonas Tampier
- javascript
0 Bert Randolf0 molily0 Struppi0 Jonas Tampier0 Struppi
Anhand folgender Datei kann man ziemlich gut sehen was ich meine. Ich habe meine Probleme in den Kommentaren festgehalten.
<html>
<head>
<title>HTML test</title>
<script type="text/javascript">
function extendedElement(elm) {
this.element = elm;
this.echo = function() {
alert(this); /* ist beim direkten Aufruf die KlassenInstanz
aber beim Aufruf über onmouseover das element von dem der Event stammt */
alert( "has the value: " + this.element.value); /* hier möchte ich evtl.
noch andere eigenschaften der Instanz benutzen */
}
this.element.onmouseover = this.echo; //event anhängen
}
</script>
</head>
<body>
<input id="a" value="A" /> <br />
<script type="text/javascript">
eA = new extendedElement(document.getElementById("a"));
alert(eA.element.value);
eA.echo();
</script>
</body>
</html>
Hallo,
Anhand folgender Datei kann man ziemlich gut sehen was ich meine. Ich habe meine Probleme in den Kommentaren festgehalten.
alert(this); /* ist beim direkten Aufruf die KlassenInstanz
aber beim Aufruf über onmouseover das element von dem der Event stammt */
alert( "has the value: " + this.element.value); /* hier möchte ich evtl.
noch andere eigenschaften der Instanz benutzen */
}
this.element.onmouseover = this.echo; //event anhängen
ich kann keine Probleme in deinen Kommentaren entdecken.
Bert
ich kann keine Probleme in deinen Kommentaren entdecken.
Stimmt, das habe ich offensichtlich nicht explizit hingeschrieben.
Der Code verursacht eine Fehlermeldung beim onmouseover über dem Input-Feld, weil "this" verschieden interpretiert wird, wie es in der einen Kommetarzeile beschrieben ist:
alert(this); /* ist beim direkten Aufruf die KlassenInstanz
aber beim Aufruf über onmouseover das element von dem der Event stammt */
Hallo,
schickt das?
this.elem = elm;
this.echo = function() {
alert(this); /* ist beim direkten Aufruf die KlassenInstanz
aber beim Aufruf über onmouseover das element von dem der Event stammt */
alert( "has the value: " + elm.value); /* hier möchte ich evtl.
noch andere eigenschaften der Instanz benutzen */
}
Bert
Hallo,
function extendedElement(elm) {
this.element = elm;
this.echo = function() {
alert(this); /* ist beim direkten Aufruf die KlassenInstanz
aber beim Aufruf über onmouseover das element von dem der Event stammt */
alert( "has the value: " + this.element.value); /* hier möchte ich evtl.
noch andere eigenschaften der Instanz benutzen */
Mir ist keine Möglichkeit bekannt, wie du umgehen kannst, dass this immer auf das Objekt zeigt, dem der Event passierte. Die Browser missachten hier anscheinend konsequent, dass echo eine Methode eines anderen Objektes ist.
Auf http://www.quirksmode.org/js/this.html wird beschrieben, dass in jedem Fall das Funktionsobjekt kopiert wird und die Funktion echo somit zum input-Elementobjekt gehört. Sie wird also gar nicht mehr als Methode eines extendedElement-Objektes aufgerufen. Du hättest sie also auch außerhalb bzw. ein allen Möglichkeiten Zusammenhängen deklarieren können, es käme auf dasselbe heraus. Dass das selbst bei addEventListener der Fall ist, verblüfft mich schon. Nach reinen ECMAScript-Regeln hast du Recht: this sollte auf eA als Instanz von extendedElement zeigen.
Du könntest höchstens beide Objekte miteinander verknüpfen:
this.element = elm; (wie gehabt)
this.element.extendedElement = this;
In echo hast du dann über this.extendedElement Zugriff auf das zugehörige extendedElement-Objekt und du kannst auf dessen Eigenschaften und Funktionen zugreifen.
Andererseits, was hast du letztlich konkret vor, also über dein Beispiel hinaus? Du könntest wahrscheinlich ohne new arbeiten und einfach eine Funktion ausführen, die das input-Elementobjekt mit gewissen Eigenschaften und Funktionen versorgt:
function extendedElement (obj) {
obj.eigenschaft = ...;
obj.funktion = function (...) {...}
}
var input1 = document.getElementById("a");
extendedElement(input1);
alert(input1.eigenschaft);
input1.funktion(...);
usw.
Im Übrigen spricht man bei JavaScript von Prototypen, nicht von Klassen.
Mathias
Vielen Dank,
Da muss ich wohl erstmal eine Weile mit verschiedenen Methoden experimentieren, bis ich das optimale Ergebnis erreicht habe.
Der Link ist sehr hilfreich und erklärt Einiges, was mir schon häufiger seltsam vorkam.
Im Moment probiere ich nur herum, wie man anständige, wiederverwendbare Objekte mit JavaScript schreibt. Das ganze soll dann auf Dinge wie DHTML tooltips (ich weiss gibt es schon), und z.B. eine Input-Feld/Select-box Kombination hinauslaufen.
Das ist damit schon das zweite Mal, daß ich von Dir sehr fundierte Informationen bezgl. JavaScript bekomme :)
Jonas
Hallo,
Im Moment probiere ich nur herum, wie man anständige, wiederverwendbare Objekte mit JavaScript schreibt.
Gar nicht? *scnr*
Damit JavaScript als OOP-Sprache funktioniert, fehlt die klare Trennung zwischen Klassen und Objekten, also Instanzen. Diese existiert nur bei den vorgefertigten Objekten (Image, Array ...) und in den vorgefertigten Interfaces (HTMLElement, HTMLCollection ...). Selbst erstellte "Objekte" sind/müssen ja, zum Zeitpunkt des Erzeugens mit dem new-Operator, bereits als Objekte (Funktionen) im Arbeitsspeicher vorhanden sein. New kopiert dann einfach nur noch das vorhandene Objekt (Prototyp-Funktion) in eine neue Variable.
Folgendes Beispiel zeigt dies und auch, wie hier "this" zu verstehen ist. Nach dem Kopieren des Prototyps mit "new" erbt die Objektvariable alle Eigenschaften und Funktionen, die der Prototyp mit "this" freigibt.
<html>
<head>
<title>HTML test</title>
<script type="text/javascript">
function extendedElement(elm) {
//Prototypbeschreibung
var private = "geheim"; //eine private-Eigenschaft
var element = elm;
var echo = function() {
alert( "Object: " + element.tagName + "\n" + "value: " + element.value + "\n" + "type: " + element.type + "\n" + "style.width: " + element.style.width + "\n" + private);
}
element.onmouseover = echo;
//veröffentlichte "Eigenschaft"
this.element = element;
//veröffentlichte "Methode"
this.echo = echo;
}
</script>
</head>
<body>
<h1 id="a">Ueberschrift</h1>
<p><input id="b" value="A" maxlength="10" style="width:300px;"></p>
<p><input id="c" type="button" value="B" style="width:30px;"></p>
<p id="d" style="width:100px;">Textabsatz</p>
<script type="text/javascript">
var eA = new extendedElement(document.getElementById("a"));
var eB = new extendedElement(document.getElementById("b"));
var eC = new extendedElement(document.getElementById("c"));
//veröffentlichte Eigenschaften/Methoden aufrufen:
alert(eC.element.value);
eC.echo();
//alert(eC.private); //Fehler
extendedElement(document.getElementById("d"));
</script>
</body>
</html>
viele Grüße
Axel
function extendedElement(elm) {
this.element = elm;
this.echo = function() {
alert(this); /* ist beim direkten Aufruf die KlassenInstanz
aber beim Aufruf über onmouseover das element von dem der Event stammt */
alert( "has the value: " + this.element.value); /* hier möchte ich evtl.
noch andere eigenschaften der Instanz benutzen */
}
this.element.onmouseover = this.echo; //event anhängen
}
this.echo ist immer nur eine Referenz auf eine Funktion, also ein Wert, den du zuweist.
Beim Aufruf der Funktion wird der Bezug zu *this* jedesmal neu erzeugt und nicht in dem Moment wo du dem Event die Referenz auf die Funktion angibst, da ja this kein festehender Wert ist sondern jedesmal neu vergeben wird.
Dir bleibt, wenn du es so machen willst wie bisher, nur der Umweg über ein zusätzliches Objekt.
function extendedElement(elm) {
this.element = elm;
this.element.parent = this;
this.echo = function() {
alert(this.parent);
alert( "has the value: " + this.value);
}
this.element.onmouseover = this.echo; //event anhängen
}
Struppi.
Dir bleibt, wenn du es so machen willst wie bisher, nur der Umweg über ein zusätzliches Objekt.
...
this.element.parent = this;
Bedeutet das, dass hier eine weitere Kopie des Objektes erstellt wird, oder ist das nur eine Referenz?
Jonas
...
this.element.parent = this;Bedeutet das, dass hier eine weitere Kopie des Objektes erstellt wird, oder ist das nur eine Referenz?
Eine Referenz.
Struppi.