+OBJEKTE + Definieren von Methoden
MichaelR
- javascript
Hallo,
bin gerade dabei mein Theoriewissen über die Objekte, welche ich selber einer HTML Seite hinzufügen kann mittels myObj = new ObjectDef(); etc..
Dabei lese ich das Tutorial von Dan Steinman (www.dansteinman.com) zu diesem Thema - die Ausführungen zu den Browsern sind zwar alle für die 4er Generation aber die Theorie ist ja weitgehend noch aktuell.
Jetzt meine Frage:
Steinman schreibt da, wenn ich einem Objekt Methoden hinzufügen will, so solle man das am besten mit Hilfe des "prototype" machen:
Bsp:
function NeueFunktion(){
...
}
MyObject.prototype.NeueFkt = NeueFunktion;
Er schreibt weiterhin, die Variante, dass ich die Funktion gleich bei der Erzeugung des Objekts anhänge
function MyObject(){
// properties:
this.h = '';
...
// methods:
this.NeueFkt = NeueFunktion;
}
seie nicht zu empfehlen.
Grund (wenn ich das richtig verstanden hab'): alle Objekte würden jetzt "Prototyping" verwenden ?!
Frage: Ist das immer noch so, dass man besser prototype verwenden sollte, oder doch nicht ?
Grüße
Michael
Hallo MichaelR,
bin gerade dabei mein Theoriewissen über die
Objekte, welche ich selber einer HTML Seite
hinzufügen kann mittels myObj = new
ObjectDef(); etc..
Du fuegst einer HTML-Seite keine Objekte zu, du
erzeugst JS-Objekte.
Steinman schreibt da, wenn ich einem Objekt
Methoden hinzufügen will, so solle man das am
besten mit Hilfe des "prototype" machen:
Wenn du einem per new erzeugtem eine neue Methode
hinzufuegen willst, solltest du das ueber den
Prototypen machen, ja. Wenn du generell einem
Objekt eine Methode geben willst, machst du das
am besten im Konstruktor per
this.method = funktion;
Grund (wenn ich das richtig verstanden hab'):
alle Objekte würden jetzt "Prototyping"
verwenden ?!
Ich glaube, du hast da was falsch verstanden. Das
prototype-Objekt fuegt das Objekt (ja, eine
Funktion *ist* ein Objekt) *jeder* vorhandenen
Instanz des Objekts zu. Willst du also
*nachtraeglich* allen Objekten eine Methode
verpassen (oder eine vorhandene ueberschreiben),
dann ist prototype dein Freund. Willst du nur
*einer* Instanz nachtraeglich eine Methode
verpassen, solltest du das ueber
obj.method = funktion;
machen. Dabei kann obj durchaus auch this sein.
Willst du einem Objekt *generell* eine Methode
verpassen, ist die Zuweisung im Konstruktor
durchaus eine sinnvolle (und performante) Loesung.
Gruesse,
CK
Hi CK,
bin gerade dabei mein Theoriewissen über die
Objekte, welche ich selber einer HTML Seite
hinzufügen kann mittels myObj = new
ObjectDef(); etc..Du fuegst einer HTML-Seite keine Objekte zu, du
erzeugst JS-Objekte.
Meinte ich ja :)
Steinman schreibt da, wenn ich einem Objekt
Methoden hinzufügen will, so solle man das am
besten mit Hilfe des "prototype" machen:Wenn du einem per new erzeugtem eine neue Methode
hinzufuegen willst, solltest du das ueber den
Prototypen machen, ja. Wenn du generell einem
Objekt eine Methode geben willst, machst du das
am besten im Konstruktor perthis.method = funktion;
Grund (wenn ich das richtig verstanden hab'):
alle Objekte würden jetzt "Prototyping"
verwenden ?!Ich glaube, du hast da was falsch verstanden. Das
prototype-Objekt fuegt das Objekt (ja, eine
Funktion *ist* ein Objekt) *jeder* vorhandenen
Instanz des Objekts zu. Willst du also
*nachtraeglich* allen Objekten eine Methode
verpassen (oder eine vorhandene ueberschreiben),
dann ist prototype dein Freund. Willst du nur
*einer* Instanz nachtraeglich eine Methode
verpassen, solltest du das ueberobj.method = funktion;
machen. Dabei kann obj durchaus auch this sein.
Willst du einem Objekt *generell* eine Methode
verpassen, ist die Zuweisung im Konstruktor
durchaus eine sinnvolle (und performante) Loesung.
Ok, das klärt mein Problem sehr gut, danke.
Die Methoden sind alle bereits vor dem Erzeugen der Objekte vorhanden und werden - wie Du schreibst - mit
Obj.method = funktion;
angehängt.
Somit hat jedes neues Objekt beim Erzeugen bereits alle Funktionen dabei.
Ok, vielen Dank
Grüße
Michael
Hallo,
Ok, das klärt mein Problem sehr gut, danke.
Die Methoden sind alle bereits vor dem Erzeugen der Objekte vorhanden
Nur wenn du mit dem Prototyp arbeitest. Die Funktionsdefinition ist erstmal nur eine Vorlage. Mit der Konstruktormethode new wird ein generisches Objekt erzeugt, dass dann anhand dieser Vorlage um Eigenschaften und Methoden erweitert wird. Innerhalb dieser Vorlage kannst du auf dieses neue Objekt über this zugreifen.
Wenn du aber in deiner Vorlage keine Zuweisungen vornimmst und einen Prototypen hast der um Eigenschaften und Methoden erweitert wurde, dann wird das Objekt nicht um diese Eigenschaften und Methoden erweitert, sondern es hat einen prototypischen Verweis auf den Prototypen, der wiederum diese Eigenschaften und Methoden hat.
und werden - wie Du schreibst - mit
Obj.method = funktion;
angehängt.
Somit hat jedes neues Objekt beim Erzeugen bereits alle Funktionen dabei.
Nein, hier weist du der Instanz (generisches Objekt) die Methode "Irgendwas" zu. Es ist hier nur die entspr. Instanz betroffen.
bernd
Hi,
emmmmmmmm - verwirrt ....
Nur wenn du mit dem Prototyp arbeitest. Die Funktionsdefinition ist erstmal nur eine Vorlage. Mit der Konstruktormethode new wird ein generisches Objekt erzeugt, dass dann anhand dieser Vorlage um Eigenschaften und Methoden erweitert wird. Innerhalb dieser Vorlage kannst du auf dieses neue Objekt über this zugreifen.
Wenn du aber in deiner Vorlage keine Zuweisungen vornimmst und einen Prototypen hast der um Eigenschaften und Methoden erweitert wurde, dann wird das Objekt nicht um diese Eigenschaften und Methoden erweitert, sondern es hat einen prototypischen Verweis auf den Prototypen, der wiederum diese Eigenschaften und Methoden hat.und werden - wie Du schreibst - mit
Obj.method = funktion;
angehängt.
Somit hat jedes neues Objekt beim Erzeugen bereits alle Funktionen dabei.Nein, hier weist du der Instanz (generisches Objekt) die Methode "Irgendwas" zu. Es ist hier nur die entspr. Instanz betroffen.
Also die Funktion, die für das Erzeugen des Objekts zuständig ist, sieht in etwa so aus:
function NewObject(id){
// properties:
this.name = id;
this.left = 0;
this.top = 0;
[etc.]
// methods:
this.function1 = ObjFunction1;
this.function2 = ObjFunction2;
[etc.]
}
nach dem Laden der Seite wird jetzt eine bestimmte Anzahl solcher Objekte erzeugt.
D = new Array();
function Startup(){
for(var i=0; i<10; i++){
D[i] = new NewObject(i+'id');
D[i].left = 50;
[etc.]
}
}
Mit diesem Vorgehen hat doch zunächst einmal das abstrakte Objekt die Methoden und beim Erzeugen der einzelnen Instanzen bekommen diese die dann ebenfalls mit überreicht ?
Oder denk ich da falsch ?
Bei dem Prototype dachte ich eigentlich bisher, dass er sich besonders gut eignet, wenn ich für bereits vorhandene Instanzen neue Methoden anfügen will, d.h. mittels prototype bekommt das *abstrakte* Objekt die neue Methode und damit wird sie dann aucht automatisch an alle bereits erzeugten Instanzen weitergereicht ???
Grüße
Michael
Hallo,
Also die Funktion, die für das Erzeugen des Objekts zuständig ist, sieht in etwa so aus:
function NewObject(id){ // properties: this.name = id; this.left = 0; this.top = 0; [etc.]
// methods: this.function1 = ObjFunction1; this.function2 = ObjFunction2; [etc.] }
nach dem Laden der Seite wird jetzt eine bestimmte Anzahl solcher Objekte erzeugt.
D = new Array();
function Startup(){ for(var i=0; i<10; i++){ D[i] = new NewObject(i+'id'); D[i].left = 50; [etc.] } }
Mit diesem Vorgehen hat doch zunächst einmal das abstrakte Objekt die Methoden und beim Erzeugen der einzelnen Instanzen bekommen diese die dann ebenfalls mit überreicht ? Oder denk ich da falsch ?
Nö, du denkst da schon ganz richtig. Sie (Instanzen) bekommen es (Eigenschaften, Methoden) aber nicht über einen prototypischen Verweis überreicht, sondern werden hier pro Instanz neu zugewiesen, sprich es wird Speicherplatz reserviert etc.
Beispiel:
function A() { this.name = "walter"; }
var v1 = new A(); var v2 = new A();
*************** *************** +++++++++++++++
Bei dem Einsatz von Prototypen ist es anders. Dort gibt es einen Verweis auf ein prototypisches Objekt mit den genannten Eigenschaften und Methoden für alle Instanzen. Der Grund dafür liegt darin, dass der Prototyp bzw. dessen Instanz nicht mitkopiert wird, der Verweis hingegen schon.
Beispiel:
function A() { this.name = "walter"; }
function B() { } B.prototype = new A();
var v1 = new B(); var v2 = new B();
*************** +++++++++++++++ * A (Instanz) * <-- Kopie pro Instanz --- + A (Vorlage) + *************** +++++++++++++++ name="walter" *************** | #---------- Prototyp (B.prototype = new A();) ---# . | . | ....übernommener Verweis.... | Verweis . . | . . | *************** *************** +++++++++++++++
Wie du siehst hat weder v1 noch v2, als Instanz gesehen, die Eigenschaft name, sondern teilen sich ein prototypisches Objekt mit der Eigenschaft name ("walter"). Würdest du nun über B.prototype.name den Namen ändern (z.B. "dieter"), dann würde auch v2, da auf die Eigenschaft name über den prototypischen Verweis zugegriffen wird, davon betroffen sein.
Anders verhält es sich bei einer Zuweisung einer Eigenschaft oder Methode an eine Instanz. Diese wird, weil es sich letztendlich um ein generisches Objekt handelt, dynamisch um die Eigenschaft bzw. Methode erweitert.
Beispiel:
function A() { this.name = "walter"; }
function B() { } B.prototype = new A();
var v1 = new B(); var v2 = new B();
v1.name = "dieter";
*************** +++++++++++++++ * A (Instanz) * <-- Kopie pro Instanz --- + A (Vorlage) + *************** +++++++++++++++ name="walter" *************** | #---------- Prototyp (B.prototype = new A();) ---# . | . | ....übernommener Verweis.... | Verweis . . | . . | *************** *************** +++++++++++++++
Ein alert(v1.name) gibt "dieter" aus, wohingegen ein alert(v2.name) "walter" ausgibt. In Wirklichkeit ist es aber noch wesentlich komplexer, kann aber nicht in einem Post erklärt werden.
Bei dem Prototype dachte ich eigentlich bisher, dass er sich besonders gut eignet, wenn ich für bereits vorhandene Instanzen neue Methoden anfügen will, d.h. mittels prototype bekommt das abstrakte Objekt die neue Methode und damit wird sie dann aucht automatisch an alle bereits erzeugten Instanzen weitergereicht ???
Genau, wie die "Grafik" es anschaulich zeigt, teilen sich dann die entspr. Instanzen das prototypische Objekt. Sie verlangen dadurch wesentlich weniger Resourcen und sind in ihrer Erzeugung schneller (Speicherreservierung, Codeauswertung) weil es nur einmal geschieht (für das prototypische Objekt). Sinn mach dies aber wirklich nur bei Methoden, weil diese sich meisten nicht ändern und somit unbedenklich geteilt werden könne, wohingegen Eigenschaften sicherlich für jede Instanz neu gesetzt werden (die Werte).
Ich hoffe dass ich mich etwas klarer ausgedrückt habe. Falls jemand Fehler sieht möge er mich korrigieren.
bernd.
Hi Bernd,
danke für die ausführlichen Infos !
Viele Grüße
Michael