Albu
New member
Array ist genauso wie Object, Date, Math, Screen oder String (usw.) eine Klasse in JS. Das ganze DOM ist aus Objekten/Klassen zusammengebaut. Vermutlich sind alle Klassen in JS von Object abgeleitet, so daß Object die Mutter allen Übels ist
Dadurch erben alle abgeleiteten (Kinder-) Klassen/Objekte die Eigenschaften und Funktionen von Object.
Der Vorteil bei JS gegenüber C++ ist, das man jederzeit jede beliebige Funktion eines Objektes oder der ganze Klasse verändern, hinzufügen oder löschen kann. Bei C++ ist dies z.B. zur Laufzeit nicht möglich.
Der Unterschied zwischen Objekt und Klasse in JS ist, wie in anderen OOP Sprachen, daß Objekte Instanzen einer Klasse sind. Array, Object, Date, Math, Screen usw. sind zunächst einmal alles Klassen. Allerdings sind z.B. Math und Screen automatisch verfügbar, d.h. sie werden vom Browser automatisch unter dem Namen Math oder Screen instanziert, oder die Funktionen sind statisch definiert, d.h. man benötigt keine Instanz zum Aufrufen der Funktionen (was der wahrscheinlichere Fall sein wird).
Instanzen werden entweder direkt (über new) oder indirekt (z.B. alle Objekte des DOMs eines konkreten HTML Dokuments oder ["1", "2", ...]) angelegt.
Wenn man eine Instanz einer Klasse angelegt hat, dann kann man alle Funktionen und Eigenschaften benutzen, ohne daß andere Instanzen / Objekte davon beeinflußt werden.
Zwei der wichtigsten Klassen zur Abbildung von Daten und Datenstrukturen sind dabei Object und Array. Die Funktion von Array erschließt sich dem (angehenden) Programmierer fast sofort, Object (hab ich in Selfhtml noch nicht gefunden) hat irgendwie weder Funktionen, noch Eigenschaften, ist eigentlich eine leere Klasse, deren Instanzen keine Funktion haben können. Falsch!
Da ich jederzeit neue Eigenschaften und Funktionen zu jedem Objekt und zu jeder Klasse definieren kann, kann ich auch das Objekt einer sinnvollen Aufgabe zuführen.
Ein neues Object lege ich ganz einfach so an:
myCoords = new Object ();
Da myOb noch leer ist, kann ich zunächst nichts damit anfangen. Wenn ich es aber mit Leben fülle, dann wird es plötzlich ein sinnvolles Objekt:
myCoords.x = 100;
myCoords.y = 200;
Jetzt habe ich ein Objekt, welches die beiden Variablen x und y enthält. Wenn ich jetzt also Funktionen zur Bearbeitung von Koordinaten benutze/schreibe, dann kann ich nun statt zwei Parametern ein Objekt mit den zwei Werten übergeben, die Parameterzahl verringert sich (natürlich muß die Empfänger-Funktion entsprechend angepaßt werden).
Der Zugriff auf die Eigenschaften erfolgt dann ganz normal:
myCoords.x oder myCoords ["x"]
Wie man sehen kann kann auch der Zugriff über den Array Operator ([]) erfolgen. Dies erlaubt es die Klasse Object als Hash zu mißbrauchen. Ein Hash ist im Grunde ein Array, welches nicht fortlaufend durchnummeriert ist, sondern als Schlüssel eben Texte oder Strings verwendet. Dies eignet sich z.B. dafür, wenn man auf Daten zugreifen möchte, die nicht über eine eindeutige Zahl referneziert werden können, bzw. wo dies nicht sinnvoll ist. Wenn ich also fünf Einträge aus der DB habe, die mit den IDs 5, 7, 100, 560 und 10020 versehen sind, dann wäre es dumm daraus ein Array zu machen und die ID als Index zu benutzen, denn dann würde ein Array enstehen, welches 10021 Einträge hätte.
Bei einem Hash habe ich nur 5 Einträge, und da ein Hash i.d.R. auch mit entsprechenden internen Datenstrukturen wie Binärbäume (oder ähnliches) arbeitet, ist der Zugriff trotz Strings ziemlichschnell.
Ein Object kann man, wie auch die Arrays, indirekt instanzieren:
myCoords = {x: 100, y:200};
oder auch direkt beim Aufruf einer Funktion:
calcCoords ({x: 100, y:200});
Für Arrays gilt nahezu das gleiche, außer das ein Array schon fertige Funktionen mitbringt, die den Umgang mit einem Array erleichtern.
Lediglich die indirekte Instanzierung ist anders, damit JS unterscheiden kann, ob ein Object oder ein Array erzeugt werden soll:
myArr = [1, 2, 3];
myArr = new Array (1, 2, 3);
myArr = new Array ();
myArr.push (1);myArr.push (2);myArr.push (3);
das Ergebnis ist identisch.
Soweit so gut. Es steht natürlich jedem offen diese beiden Datenstrukturen zusammen mit konventionellen Variablentypen zu kombinieren und zu verschachteln.
also z.B.
myMatrix = [{x: 1, y: 0, z: 0}, {x: 0, y: 1, z: 0}, {x: 0, y: 0, z: 1}]
so kann jede erdenkliche Datenstruktur erzeugt werden.
Jetzt nochmal zurück zur Aussage, daß man Funktionen und Eigenschaften jederzeit an bestehende Objekte und Klassen anhängen kann. Das man einfach einem leeren Objekt vom Typ Object neue Eigenschaften (x, y) anhängen kann, konnte man oben sehen. Neue Funktionen sind auch kein Problem:
myCoords.setCoords = function (x,y) { this.x = x; this.y = y; }
Will ich gleich allen Objekten einer Klasse eine neue Funktion spendieren, dann kann ich natürlich jedesmal beim Instanzieren diese Funktion hinzufügen, was darin resultiert, daß ich aufpassen muß, keine zu vergessen und einem Haufen Speicherplatz, der durch n Kopien der gleichen Funktion in jeder einzelnen Instanz verschwendet wird. Besser wäre es hier die Funktion gleich der ganzen Klasse zur Verfügung zu stellen. Auch dies geht:
Object.prototype.setCoords = function (x,y) { this.x = x; this.y = y; }
Schon haben alle Instanzen von Object die Funktion setCoords. Ob sie nun wollen oder nicht. Da aber alle anderen Objekte von Object abgeleitet sind, heißt das, daß auch alle Arrays, Strings, usw. diese Funktion jetzt besitzen. Was natürlich nicht unbedingt so gut ist, da ja nur Koordinaten Objekte diese Funktion besitzen sollten. Und da man nach Möglichkeit sehr vorsichtig sein sollte mit dem Hinzufügen von neuen Funktionen an bestehende Klassen, um möglichst wenig Nebenwirkungen zu verursachen und man also den minimalst möglichen Einschnitt machen sollte, ist es selten eine gute Idee an Object selbst ranzutreten.
Wenn man aber Funktionen zur Array Bearbeitung basteln möchte, dann sollte man sie so allgemein halten, damit man sie problemlos an die Array Klasse anhängen kann.
Vorsichtig muß man sein, wenn man Standard-Funktionen umschreibt. Ich könnte ja z.B. die sort Funktion des Arrays umschreiben, um dort meine eigene Sortierung zu programmieren. Allerdings ist diese dann in JS und nicht in Assembler geschrieben, was für einen Geschwindigkeitsnachteil sorgt. Außerdem betrifft es eben alle Arrays und das könnte negative Auswirkungen auf andere intere Array Objekte haben, die man gar nicht vorheresagen kann. Solche Funktionen sollte man also nur überschreiben, wenn man genau weiß, was man tut, bzw. sollte sie nur in einer einzelnen Instanz überschreiben, denn dann wirkt sie nur dort, alle anderen Arrays benutzen die eingebaute sort Funktion.
Um wieder zum Koordinaten Objekt zurückzukommen, wenn man hier eigene Funktionen definieren will, dann ist es sinnvoll eine ganz eigene Klasse zu definieren. Dies geht in JS folgendermaßen:
CCoordinates = function (x, y)
{
// constructor
this.init ();
this.setCoords (x, y);
}
// erbt von Object [optional]
CCoordinates.prototype = new Object ();
CCoordinates.prototype.init = function ()
{
// initialize
x = 0; y = 0;
}
CCoordinates.prototype.setCoords = function (x, y)
{ this.x = x; this.y = y; }
myCoords = new CCoordinates (100, 200);
alert (myCoords.x + ";" + myCoords.y);
So das waren eine Menge Infos, ich habe alles soweit auf Lauffähigkeit (im Opera
) getestet, das Gesagte gilt 1:1 auch für Actionscript, d.h. kann man es genauso gut auch in Flash verwenden (mit Ausnahme des "alert"s
).
Der Vorteil bei JS gegenüber C++ ist, das man jederzeit jede beliebige Funktion eines Objektes oder der ganze Klasse verändern, hinzufügen oder löschen kann. Bei C++ ist dies z.B. zur Laufzeit nicht möglich.
Der Unterschied zwischen Objekt und Klasse in JS ist, wie in anderen OOP Sprachen, daß Objekte Instanzen einer Klasse sind. Array, Object, Date, Math, Screen usw. sind zunächst einmal alles Klassen. Allerdings sind z.B. Math und Screen automatisch verfügbar, d.h. sie werden vom Browser automatisch unter dem Namen Math oder Screen instanziert, oder die Funktionen sind statisch definiert, d.h. man benötigt keine Instanz zum Aufrufen der Funktionen (was der wahrscheinlichere Fall sein wird).
Instanzen werden entweder direkt (über new) oder indirekt (z.B. alle Objekte des DOMs eines konkreten HTML Dokuments oder ["1", "2", ...]) angelegt.
Wenn man eine Instanz einer Klasse angelegt hat, dann kann man alle Funktionen und Eigenschaften benutzen, ohne daß andere Instanzen / Objekte davon beeinflußt werden.
Zwei der wichtigsten Klassen zur Abbildung von Daten und Datenstrukturen sind dabei Object und Array. Die Funktion von Array erschließt sich dem (angehenden) Programmierer fast sofort, Object (hab ich in Selfhtml noch nicht gefunden) hat irgendwie weder Funktionen, noch Eigenschaften, ist eigentlich eine leere Klasse, deren Instanzen keine Funktion haben können. Falsch!
Da ich jederzeit neue Eigenschaften und Funktionen zu jedem Objekt und zu jeder Klasse definieren kann, kann ich auch das Objekt einer sinnvollen Aufgabe zuführen.
Ein neues Object lege ich ganz einfach so an:
myCoords = new Object ();
Da myOb noch leer ist, kann ich zunächst nichts damit anfangen. Wenn ich es aber mit Leben fülle, dann wird es plötzlich ein sinnvolles Objekt:
myCoords.x = 100;
myCoords.y = 200;
Jetzt habe ich ein Objekt, welches die beiden Variablen x und y enthält. Wenn ich jetzt also Funktionen zur Bearbeitung von Koordinaten benutze/schreibe, dann kann ich nun statt zwei Parametern ein Objekt mit den zwei Werten übergeben, die Parameterzahl verringert sich (natürlich muß die Empfänger-Funktion entsprechend angepaßt werden).
Der Zugriff auf die Eigenschaften erfolgt dann ganz normal:
myCoords.x oder myCoords ["x"]
Wie man sehen kann kann auch der Zugriff über den Array Operator ([]) erfolgen. Dies erlaubt es die Klasse Object als Hash zu mißbrauchen. Ein Hash ist im Grunde ein Array, welches nicht fortlaufend durchnummeriert ist, sondern als Schlüssel eben Texte oder Strings verwendet. Dies eignet sich z.B. dafür, wenn man auf Daten zugreifen möchte, die nicht über eine eindeutige Zahl referneziert werden können, bzw. wo dies nicht sinnvoll ist. Wenn ich also fünf Einträge aus der DB habe, die mit den IDs 5, 7, 100, 560 und 10020 versehen sind, dann wäre es dumm daraus ein Array zu machen und die ID als Index zu benutzen, denn dann würde ein Array enstehen, welches 10021 Einträge hätte.
Bei einem Hash habe ich nur 5 Einträge, und da ein Hash i.d.R. auch mit entsprechenden internen Datenstrukturen wie Binärbäume (oder ähnliches) arbeitet, ist der Zugriff trotz Strings ziemlichschnell.
Ein Object kann man, wie auch die Arrays, indirekt instanzieren:
myCoords = {x: 100, y:200};
oder auch direkt beim Aufruf einer Funktion:
calcCoords ({x: 100, y:200});
Für Arrays gilt nahezu das gleiche, außer das ein Array schon fertige Funktionen mitbringt, die den Umgang mit einem Array erleichtern.
Lediglich die indirekte Instanzierung ist anders, damit JS unterscheiden kann, ob ein Object oder ein Array erzeugt werden soll:
myArr = [1, 2, 3];
myArr = new Array (1, 2, 3);
myArr = new Array ();
myArr.push (1);myArr.push (2);myArr.push (3);
das Ergebnis ist identisch.
Soweit so gut. Es steht natürlich jedem offen diese beiden Datenstrukturen zusammen mit konventionellen Variablentypen zu kombinieren und zu verschachteln.
also z.B.
myMatrix = [{x: 1, y: 0, z: 0}, {x: 0, y: 1, z: 0}, {x: 0, y: 0, z: 1}]
so kann jede erdenkliche Datenstruktur erzeugt werden.
Jetzt nochmal zurück zur Aussage, daß man Funktionen und Eigenschaften jederzeit an bestehende Objekte und Klassen anhängen kann. Das man einfach einem leeren Objekt vom Typ Object neue Eigenschaften (x, y) anhängen kann, konnte man oben sehen. Neue Funktionen sind auch kein Problem:
myCoords.setCoords = function (x,y) { this.x = x; this.y = y; }
Will ich gleich allen Objekten einer Klasse eine neue Funktion spendieren, dann kann ich natürlich jedesmal beim Instanzieren diese Funktion hinzufügen, was darin resultiert, daß ich aufpassen muß, keine zu vergessen und einem Haufen Speicherplatz, der durch n Kopien der gleichen Funktion in jeder einzelnen Instanz verschwendet wird. Besser wäre es hier die Funktion gleich der ganzen Klasse zur Verfügung zu stellen. Auch dies geht:
Object.prototype.setCoords = function (x,y) { this.x = x; this.y = y; }
Schon haben alle Instanzen von Object die Funktion setCoords. Ob sie nun wollen oder nicht. Da aber alle anderen Objekte von Object abgeleitet sind, heißt das, daß auch alle Arrays, Strings, usw. diese Funktion jetzt besitzen. Was natürlich nicht unbedingt so gut ist, da ja nur Koordinaten Objekte diese Funktion besitzen sollten. Und da man nach Möglichkeit sehr vorsichtig sein sollte mit dem Hinzufügen von neuen Funktionen an bestehende Klassen, um möglichst wenig Nebenwirkungen zu verursachen und man also den minimalst möglichen Einschnitt machen sollte, ist es selten eine gute Idee an Object selbst ranzutreten.
Wenn man aber Funktionen zur Array Bearbeitung basteln möchte, dann sollte man sie so allgemein halten, damit man sie problemlos an die Array Klasse anhängen kann.
Vorsichtig muß man sein, wenn man Standard-Funktionen umschreibt. Ich könnte ja z.B. die sort Funktion des Arrays umschreiben, um dort meine eigene Sortierung zu programmieren. Allerdings ist diese dann in JS und nicht in Assembler geschrieben, was für einen Geschwindigkeitsnachteil sorgt. Außerdem betrifft es eben alle Arrays und das könnte negative Auswirkungen auf andere intere Array Objekte haben, die man gar nicht vorheresagen kann. Solche Funktionen sollte man also nur überschreiben, wenn man genau weiß, was man tut, bzw. sollte sie nur in einer einzelnen Instanz überschreiben, denn dann wirkt sie nur dort, alle anderen Arrays benutzen die eingebaute sort Funktion.
Um wieder zum Koordinaten Objekt zurückzukommen, wenn man hier eigene Funktionen definieren will, dann ist es sinnvoll eine ganz eigene Klasse zu definieren. Dies geht in JS folgendermaßen:
CCoordinates = function (x, y)
{
// constructor
this.init ();
this.setCoords (x, y);
}
// erbt von Object [optional]
CCoordinates.prototype = new Object ();
CCoordinates.prototype.init = function ()
{
// initialize
x = 0; y = 0;
}
CCoordinates.prototype.setCoords = function (x, y)
{ this.x = x; this.y = y; }
myCoords = new CCoordinates (100, 200);
alert (myCoords.x + ";" + myCoords.y);
So das waren eine Menge Infos, ich habe alles soweit auf Lauffähigkeit (im Opera