Ich bin ein JavaScript Anfänger. Vor dem aktuellen Projekt gab es nur ein bisschen Html mit JavaScript als DOM Manipulator dazwischen. Echte Profis werden sicher nichts lernen können.
Ein Problem bei JavaScript ist, dass das Web voller kleiner Snippets ist, die tolle Sachen im Browser anstellen. Man findet nicht sehr viel zu den Konzepten der Sprache. JavaScript ist eine gute Ergänzung zu Html, weil es ebenso tolerant ist. Kein Compiler achtet auf die Typisierung, implizite Typkonvertierung überall.
Natürlich kann eine Sprache, die sehr schnell zu "es funktioniert" führt, auch zu unsauberem Code verleiten. Wer die Sprache konzeptionell missbraucht gerät in Gefahr, über unangenehme Randbedingungen zu stolpern, die nicht mehr funktionieren.
Ein Beispiel sind zwei sehr häufig benötigte Konstruktionen, das Array und die Hashtable.
JavaScript verfügt über ein Array Objekt das sich wie erwartet verhält. Nur ein bisschen dynamischer. So passt sich die Länge zum Beispiel automatisch an:
var testArray = new Array();
testArray[0] = "Test0";
testArray[99] = "Test99";
// Der Test liefert true:
if (testArray.length = 100)
result = "Array Länge: 100";
Für die Hashtable gibt es aber kein entsprechendes Objekt. Aber dafür gibt es eine sehr interessante Eigenschaft von JavaScript. Alle Eigenschaften (und Methoden) eines Objekt sind, wie für eine dynamische Sprache zu erwarten, dynamisch. Können also zu jeder Zeit verändert werden. Der JavaScript Interpreter verwaltet diese Eigenschaften offensichtlich in einer Hashtable. Diese Objekt-Hashtable steht auch dem Entwickler zur Verfügung. Eine Einschränkung hat diese Objekt-Hashtable aber: Nachdem Objekt Eigenschaften benannt sind, können die Keys der Hashtable auch entsprechend nur Namen oder allgemeiner Zeichenketten sein. Genauso können natürlich als Hash Key keine Schlüsselworte des Core Objects verwendet werden (z. B: "toString").
var hashObject = new Object();
// Werte zuweisen
hashObject["key1"] = "Wert1";
hashObject["key2"] = 1234;
// Werte auslesen über Hashtable
var test = hashObject["key1"];
// Werte auslesen über Eigenschaft
var test2 = hashObject.key2
// Test, ob ein Wert vorhanden ist
if (hashObject.hasOwnProperty("key1"))
result = "vorhanden";
Mit der for...in und der for each...in Schleife kann man ganz einfach über die Schlüsselworte oder Schlüsselwerte der Objekt-Hashtable iterieren.
for (key in hashObject)
allKeys += key;
Bis dahin kann man das alles ganz einfach aus der JavaScript Referenz lernen. Leider liest man nicht immer die komplette Dokumentation, bevor man sich in einer neuen Sprache austobt. Google liefert zu jeder Frage sehr viele kleine Lösungen. Leider kann Google die Qualität des Codes nicht beurteilen. Schlechter Code prominent platziert führt zu neuen Programmierern mit schlechtem Stil.
Der häufigste Fehler in diesem Zusammenhang ist, dass man das Array als Hashtable verwendet:
var newHashObject = new Array();
JavaScript ist eine objektbasiert Skriptsprache und damit ist auch das Array ein Objekt. Damit funktioniert zunächst alles wie bisher. Trotzdem sollte man das so nicht machen.
Erstens leidet die Lesbarkeit. Wenn man Array definiert, erwartet man ein Array. Wenn der Zugriff dann über Variablen erfolgt, ahnt man vielleicht nicht, dass gar keine Array Indizes, sondern Hashtable Keys verwandt werden:
var result = hashObject[item];
Ist item ein Integer, mit dem auf das Array zugegriffen wird? Oder ist item ein String, mit dem auf eine Objekt Eigenschaft zugegriffen wird?
Auch der Entwickler kann sich selbst verwirren. Die Länge des Arrays wird über length abgefragt. Missbraucht man das Array als Objekt-Hashtable liefert length natürlich den falschen Wert (0).
Richtig ärgerlich wird es aber dann bei dem in Operator, der unter anderem in den Schleifen zum Einsatz kommt. Eigenschaften der vordefinierten Core Objekte werden dabei nicht ausgegeben. Nur per Code definierte Eigenschaften werden berücksichtigt, dafür aber über die ganze Prototypen Hierarchie (JavaScripts quasi Vererbung).
Ich wollte zum Beispiel das Array per Prototype um eine contains Methode erweitern.
Array.prototype.contains = function(element)
{
for (var i = 0; i < this.length; i++)
{
if (this[i] == element)
{
return true;
}
}
return false;
};
Diese Erweiterung funktioniert toll. Nur jedes Array hat jetzt ein weiteres Hash Element mit dem Key contains. Bei einer Schleife wird dieses Element mit ausgegeben. Und zwar bei jeder Objekt-Hashtable, die fälschlicherweise mit "new Array" statt "new Object()" definiert wurde.
Merke: Kein Array verwenden, wenn eigentlich nur ein Object gebraucht wird!