
In any project, there will be a certain amount of unknown. This is the nature of our work. schreibt Ka Wai Cheung in the developer’s code. Bei der Frontend-Entwicklung beziehe ich diesen Satz zumeist auf die "große Unbekannte" – den Client (von der Hard- und Software bis hin zum Interaktionsverhalten), aber auch die Sprache JavaScript und ihre Implementationen bieten immer wieder echte Überraschungen.
Eine triviale Aufgabe: ein Datum validieren und mit einem anderen Datum vergleichen, dabei kann das Datum eine gewisse Varianz in der Reihenfolge und Schreibweise haben. Ich betrachtete kurz die bereits implementierte Bestandslösung für die Validierung und war erstaunt über das mühsame Arbeiten mit substr. Das kann man doch eleganter lösen: Ein regulärer Ausdruck für die Validierung, dient gleichzeitig der Zerlegung des Datums, um daraus dann ein Date Objekt für den Vergleich zu erstellen:
// eine Pruefung unter vielen, Abbruch der gesamten Pruefung wenn fehlerhaft...
proceed = false;
var date_test = [ '07-11-2011' , '05-11-2011' ];
var date_regexp = /^(0[1-9]|[12][0-9]|3[01])[- /.](0[1-9]|1[012])[- /.](19|20)\d\d$/;
if( date_test[0].match( date_regexp ) &&
date_test[1].match( date_regexp ) ) {
temp = date_test[0].split( date_regexp );
date_A = new Date();
date_A.setFullYear( temp[3], ( temp[2] -1 ) , temp[1] );
temp = date_test[1].split( date_regexp );
date_B = new Date();
date_B.setFullYear( temp[3], ( temp[2] -1 ) , temp[1] );
// Datum A muss vor Datum B liegen
if( date_A < date_B ) {
proceed = true;
}
}
// Ende der Pruefung - nun Entscheidung...
alert( proceed ); // Test Ausgabe
...Auf den ersten Blick schien alles zu funktionieren. Wie erwartet wird "false" ausgegeben - Task erledigt, Ticket schließen, Feierabend machen. Nächster Morgen - Ticket ist wieder auf: Die Erweiterung funktioniert nicht. Alle folgenden Prüfungen werden nicht mehr ausgeführt, unabhängig vom Datum. Kann nicht sein, ich hatte das Datum definitiv mehrfach verändert, um alle Variationen zu kontrollieren. Teste daraufhin die Anwendung im Firefox erneut - alles wie gewünscht, Screenshots an das Ticket gehängt, Rückmeldung. Geht Nicht! Noch ein Test, diesmal im Internet Explorer, und siehe da, im Internet Explorer bleibt proceed immer false.
Ein Fehler im regulären Ausdruck? Nicht wirklich, denn der match funktioniert cross-browser. Aber das Datum ist im Internet Explorer NaN während alle anderen getesteten Browser das korrekte Datum ausgeben. Scheitern tut das ganze am split. Laut Spezifikation kann die String Methode sowohl mit Zeichenketten, als auch regulären Ausdrücken umgehen. De facto gibt es da aber einige Unterschiede:
var test_string = 'a,b,c,,,d,e,f,g';
// Split mit Zeichenkette
// Erwartet: 9 -> Ergebnis ist 9
var test_a = test_string.split(',');
alert(test_a.length);
// Split mit regulärem Ausdruck:
// Erwartet: 9 -> Ergebnis ist im IE: 7
var test_b = test_string.split(/,/);
alert(test_b.length);Die Methode split reagiert eindeutig anders als die Methode exec des RegExp Objektes. Ändert man das ursprüngliche Script wie folgt:
// eine Pruefung unter vielen, Abbruch der gesamten Pruefung wenn fehlerhaft...
proceed = false;
var date_test = [ '07-11-2011' , '05-11-2011' ];
var date_regexp = /^(0[1-9]|[12][0-9]|3[01])[- /.](0[1-9]|1[012])[- /.](19|20)\d\d$/;
if( date_test[0].match( date_regexp ) &&
date_test[1].match( date_regexp ) ) {
temp = date_regexp.exec( date_test[0] );
date_A = new Date();
date_A.setFullYear( temp[3], ( temp[2] -1 ) , temp[1] );
temp = date_regexp.exec( date_test[1] );
date_B = new Date();
date_B.setFullYear( temp[3], ( temp[2] -1 ) , temp[1] );
// Datum A muss vor Datum B liegen
if( date_A < date_B ) {
proceed = true;
}
}
// Ende der Pruefung - nun Entscheidung...
alert( proceed ); // Test Ausgabe
...Dann funktioniert diese Prüfung in allen Browsern. Aber warum? Wieso verhält sich der gleiche reguläre Ausdruck bei zwei Methoden so unterschiedlich? Steven Levithan beschreibt in seinem Artikel JavaScript split Bugs: Fixed! gleich eine ganze Reihe von Fehlern (die nicht nur den Internet Explorer betreffen), und liefert auch gleich eine Lösung, in dem er die ganze Methode überlagert. Auch wenn es in meinem Fall ausgereicht hat, die Methode einfach zu wechseln - dieses Verhalten bleibt ein Mysterium. Bedeutet es doch, dass da unterschiedliche Verabeitungsprozesse ablaufen. Wenn man bedenkt, dass reguläre Ausdrücke für viele ohnehin ein Buch mit sieben Siegeln darstellt, wie passend ist es da, dass es auch noch solche Sprach-Fehler gibt.

