Auswirkungen des Dokumentmodus von Internet Explorer 8 auf JavaScript

In einem früheren Beitrag habe ich über die große Auswahl an Browser- und Dokumentmodi von Internet Explorer 8 gesprochen. Die meisten Leute sind ziemlich vertraut damit, wie sich die verschiedenen Dokumentmodi auf das Layout in Bezug auf die Implementierung von CSS auswirken, aber was verloren gegangen ist, ist, wie sich der Dokumentmodus auf die Kern-JavaScript-Engine im Browser auswirkt. Diese Änderungen sind etwas subtil, aber wichtig zu verstehen, wenn Sie mit Internet Explorer 8 arbeiten.

Vor ein paar Jahren veröffentlichte Microsoft ein Papier mit dem Titel JScript Deviations from ES3, in dem sie Wege skizzierten, in denen die JScript-Engine (das einflussreiche JavaScript des Internet Explorers) vom ECMAScript 3-Standard abgewichen war. Diese Abweichungen sind etwas harmlos, aber die Chancen stehen gut, dass Sie irgendwann in der Vergangenheit von einer oder mehreren von ihnen gebissen wurden. Bei dem Versuch von Microsoft, den Internet Explorer 8 standardkonformer zu machen, traten die gleichen Probleme, die bei CSS auftraten, auch bei JavaScript auf. Sie konnten die Abweichungen in JScript beheben, aber wenn der Browser im IE5- oder IE7-Dokumentmodus ausgeführt wurde, könnten Probleme auftreten, da diese Korrekturen möglicherweise nicht mit dem Code kompatibel sind, der auf diese Browser abzielt.

Microsoft hat sich dafür entschieden, versionierte Funktionen der JScript-Engine für Internet Explorer 8 zu erstellen. Für IE5- und IE7-Dokumentmodi verhält sich die JScript-Engine wie im tatsächlichen Internet Explorer 7, komplett mit allen Abweichungen von ECMAScript 3. Im IE8-Dokumentmodus die Abweichungen sind weg und Sie erhalten die volle Leistung der JScript-Engine.

Natives JSON

Die JScript-Engine von Internet Explorer 8 implementiert den nativen JSON Objekt Objekt wie in ECMAScript 5 definiert. Das Objekt ist jedoch nur vorhanden, wenn die Seite im IE8-Dokumentmodus ausgeführt wird. Dazu gehört der globale JSON Objekt sowie Methoden, die für die JSON-Funktionalität verwendet werden:

  • Date.prototype.toJSON()
  • Number.prototype.toJSON()
  • String.prototype.toJSON()
  • Boolean.prototype.toJSON()

Die JSON Objekt und diese Methoden im Dokumentmodus von IE5 oder IE7 sind undefiniert.

Hinweis: Obwohl Date.prototype.toJSON() wird im IE8-Dokument Date.prototype.toISOString() unterstützt ist nicht implementiert. Das ist seltsam, weil sie denselben Wert zurückgeben.

DOM-Getter/Setter

Einer der merkwürdigeren Aspekte der JScript-Engine ist, dass sie ECMAScript 5-Getter und -Setter implementiert, aber nur für DOM-Objekte und nicht für native JavaScript-Objekte. Die Implementierung besteht aus halbgaren Versionen von Object.defineProperty() und Object.getOwnPropertyDescriptor() die hauptsächlich die Get- und Set-Eigenschaften unterstützen. Zum Beispiel:

Object.defineProperty(document.body, "active", {
    set: function(value){
        document.body.className = (value !== false) ? "active" : "";
    },

    get: function(){
        return document.body.className == "active";
    }

});

var descriptor = Object.getOwnPropertyDescriptor(document.body, "innerHTML");
alert(descriptor.get);   //displays function

Beide Methoden sind nur im IE8-Dokumentmodus verfügbar und existieren in anderen Dokumentmodi nicht.

Arrays

Einer der Bereiche, in denen die JScript-Implementierung wirklich auseinanderfiel, war der Umgang mit Arrays. Arrays wiesen die meisten Abweichungen vom ECMAScript 3-Standard auf und bereiteten Entwicklern ständig Kopfschmerzen. Erstens, wenn undefined an join() übergeben wird , wurde das Argument in den String „undefined“ übersetzt und dieser wurde verwendet, um die Elemente zu verketten. Zum Beispiel:

var colors = ["red", "green", "blue"];
alert(colors.join(undefined));    //"redundefinedgreenundefinedblue" in IE7

Bei Ausführung im IE8-Dokumentmodus ein Wert von undefined wird ignoriert und das Standardtrennzeichen (ein Komma) verwendet.

Die unshift() Methode, die ein Element an den Anfang des Arrays schiebt, hatte auch eine Abweichung in JScript. Anstatt die Länge des Arrays nach dem Hinzufügen des Elements zurückzugeben, wurde einfach undefined zurückgegeben . Im IE8-Dokumentmodus wurde dies so behoben, dass unshift() gibt die Array-Länge korrekt zurück.

Die letzte große Änderung an Arrays ist die Fähigkeit, korrekt von Array zu erben Typ. Dean Edwards hat einen ganzen Beitrag über den Versuch geschrieben, einen Untertyp von Array zu erstellen und die Probleme, auf die er gestoßen ist. Das größte Problem ist das Zuweisen einer Instanz von Array Prototyp eines anderen Konstrukteurs zu sein bedeutete, dass die length Eigentum würde nicht mehr funktionieren. Beachten Sie Folgendes:

function MyArray(){
}

MyArray.prototype = new Array();
MyArray.prototype.get = function(i){
    return this[i];
};

var colors = new MyArray();
colors.push("red");
colors.push("green");
colors.sort();
alert(colors.get(0));    //"green"
alert(colors.length);    //in IE7, outputs "0"; in IE8, outputs "2"

In Internet Explorer vor Version 8 der length Eigentum von Array Der Nachkomme des Typs wurde nicht automatisch geändert, und daher war die Vererbung nur für Nicht-IE-Browser wirklich nützlich. Im IE8-Dokumentmodus wird jedoch der length -Eigenschaft funktioniert wie in anderen Browsern, während die Dokumentmodi IE5 und IE7 das alte abweichende Verhalten verwenden.

Verschiedene Fehlerbehebungen

Es gibt eine kleine Gruppe von Korrekturen, die nicht wirklich logisch kategorisiert werden können, aber dennoch dazu beitragen, dass JScript besser mit anderen JavaScript-Implementierungen übereinstimmt. Das erste ist, dass Objektliterale jetzt nachgestellte Kommas zulassen. Vor Internet Explorer 8 führte Folgendes zu einem Parsing-Fehler:

var object = {
    name: "value",
};

Das nachgestellte Komma nach dem letzten Eigenschaftswert wird von der ECMAScript 3-Syntax ausdrücklich zugelassen und ist in allen anderen Browsern zulässig. Der IE8-Dokumentmodus unterstützt diese Syntax jetzt auch korrekt (andere Dokumentmodi werfen den Fehler immer noch).

Eine weitere nette Verbesserung ist, dass der IE8-Dokumentmodus jetzt den Zugriff auf Zeichen in einer Zeichenfolge über die Klammernotation erlaubt:

var s = "Hello world!";
alert(s[0]);    //"H"

Dadurch wird JScript mit anderen JavaScript-Engines in Einklang gebracht; Die Dokumentmodi IE5 und IE7 geben weiterhin undefined zurück .

Zwei weitere Änderungen, die Sie wahrscheinlich nicht betreffen, aber erwähnenswert sind:

  • Number.prototype.toPrecision() Wird verwendet, um einen Fehler auszulösen, wenn undefined wurde übergeben. Der IE8-Dokumentmodus ruft jetzt standardmäßig Number.prototype.toString() auf in diesem Fall.
  • Error.prototype.toString() wurde richtig implementiert, um bessere Fehlermeldungen bereitzustellen.

Schlussfolgerung

Der Dokumentmodus von IE8 bietet eine ganze Reihe von Verbesserungen gegenüber Internet Explorer 7, nicht nur in CSS, sondern auch in JavaScript. Wenn Sie einen möglichst standardkonformen Code schreiben möchten, stellen Sie sicher, dass Ihre Seite im Internet Explorer 8 im IE8-Dokumentmodus ausgeführt wird (siehe meinen vorherigen Post für Details). JScript mit anderen JavaScript-Engines in Einklang zu bringen, ist ein unglaublich wichtiger Schritt. Schade, dass diese Details in den Ankündigungen von Internet Explorer 8 ziemlich übersehen wurden.