Jak režim dokumentu aplikace Internet Explorer 8 ovlivňuje JavaScript

V předchozím příspěvku jsem mluvil o široké škále režimů prohlížeče a dokumentů v aplikaci Internet Explorer 8. Většina lidí je docela obeznámena s tím, jak různé režimy dokumentu ovlivňují rozvržení z hlediska implementace CSS, ale ztratilo se to, jak režim dokumentu ovlivňuje jádro JavaScriptu v prohlížeči. Tyto změny jsou poněkud nenápadné, ale je důležité je pochopit, když pracujete s Internet Explorerem 8.

Před několika lety Microsoft publikoval článek nazvaný JScript Deviations from ES3, ve kterém nastínil způsoby, jak se engine JScript (jednomocný JavaScript Internet Exploreru) odchýlil od standardu ECMAScript 3. Tyto odchylky jsou poněkud neškodné, ale je pravděpodobné, že jste byli jednou nebo více z nich někdy v minulosti kousnuti. Ve snaze Microsoftu, aby byl Internet Explorer 8 více kompatibilní se standardy, se stejné problémy, které se objevily kolem CSS, objevily také kolem JavaScriptu. Mohli by opravit odchylky v JScriptu, ale pokud by prohlížeč běžel v režimu dokumentů IE5 nebo IE7, mohly by nastat problémy, protože tyto opravy nemusí být kompatibilní s kódem, který cílí na tyto prohlížeče.

Společnost Microsoft se rozhodla vytvořit verzované funkce enginu JScript pro Internet Explorer 8. Pro režimy dokumentů IE5 a IE7 se jádro JScript chová stejně jako ve skutečném Internet Exploreru 7, včetně všech odchylek od ECMAScript 3. Když je v režimu dokumentu IE8, odchylky jsou pryč a získáte plný výkon enginu JScript.

Nativní JSON

Motor JScript aplikace Internet Explorer 8 implementuje nativní JSON objekt objektu podle definice ECMAScript 5. Objekt je však přítomen pouze tehdy, když stránka běží v režimu dokumentu IE8. To zahrnuje globální JSON objekt a také metody používané pro funkčnost JSON:

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

JSON objekt a tyto metody v režimu dokumentu IE5 nebo IE7 nejsou definovány.

Poznámka: I když Date.prototype.toJSON() je podporováno v dokumentu IE8, Date.prototype.toISOString() není implementován. To je zvláštní, protože vracejí stejnou hodnotu.

Getter/setters DOM

Jedním z nejzajímavějších aspektů enginu JScript je, že implementuje gettery a settery ECMAScript 5, ale pouze pro objekty DOM a ne pro nativní objekty JavaScriptu. Implementace se skládá z nedodělaných verzí Object.defineProperty() a Object.getOwnPropertyDescriptor() které primárně podporují vlastnosti get a set. Například:

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

Obě metody jsou dostupné pouze v režimu dokumentu IE8 a v jiných režimech dokumentu neexistují.

Pole

Jedna z oblastí, kde se implementace JScriptu skutečně rozpadla, byla práce s poli. Pole měly nejvíce odchylek od standardu ECMAScript 3 a byly neustálým zdrojem bolestí hlavy pro vývojáře. Za prvé, pokud není definováno, je předáno do join() , argument byl přeložen do řetězce „undefined“ a ten byl použit ke zřetězení položek. Například:

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

Při spuštění v režimu dokumentu IE8 hodnota undefined je ignorován a je použit výchozí oddělovač (čárka).

unshift() Metoda, která posune položku na začátek pole, měla také odchylku v JScript. Místo vracení délky pole po přidání položky jednoduše vrátilo undefined . V režimu dokumentu IE8 to bylo opraveno tak, že unshift() správně vrátí délku pole.

Poslední velkou změnou v polích je schopnost správně dědit z Array typ. Dean Edwards má celý příspěvek o pokusu o vytvoření podtypu Array a problémy, se kterými se setkal. Největší problém je v přiřazení instance Array být prototypem jiného konstruktéra znamenalo, že length majetek už nebude fungovat. Zvažte následující:

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"

V Internet Exploreru starší než 8, length vlastnost libovolného Array potomek typu se neměnil automaticky, a tak byla dědičnost skutečně užitečná pouze pro prohlížeče bez IE. V režimu dokumentu IE8 však length vlastnost funguje jako v jiných prohlížečích, zatímco režimy dokumentů IE5 a IE7 používají staré odchylné chování.

Různé opravy

Existuje malá skupina oprav, které nelze ve skutečnosti logicky kategorizovat, ale přesto pomáhají JScriptu lépe se shodovat s jinými implementacemi JavaScriptu. První je, že objektové literály nyní umožňují koncové čárky. Před aplikací Internet Explorer 8 způsobovalo chybu analýzy následující:

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

Koncová čárka za poslední hodnotou vlastnosti je explicitně povolena syntaxí ECMAScript 3 a je povolena ve všech ostatních prohlížečích. Režim dokumentu IE8 nyní také správně podporuje tuto syntaxi (ostatní režimy dokumentu stále vyvolávají chybu).

Dalším příjemným vylepšením je, že režim dokumentu IE8 nyní umožňuje přístup ke znakům v řetězci prostřednictvím zápisu závorek:

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

To přináší JScript do souladu s ostatními JavaScript motory; Režimy dokumentů IE5 a IE7 budou stále vracet undefined .

Dvě další změny, které se vás pravděpodobně netýkají, ale stojí za zmínku:

  • Number.prototype.toPrecision() používá se k vyvolání chyby při undefined byl předán. Režim dokumentu IE8 je nyní standardně nastaven na volání Number.prototype.toString() v tomto případě.
  • Error.prototype.toString() byl správně implementován, aby poskytoval lepší chybové zprávy.

Závěr

Režim dokumentu IE8 nabízí oproti Internet Exploreru 7 celou řadu vylepšení nejen v CSS, ale také v JavaScriptu. Pokud chcete napsat kód co nejvíce vyhovující standardům, ujistěte se, že vaše stránka běží v Internet Exploreru 8 v režimu dokumentu IE8 (podrobnosti viz můj předchozí příspěvek). Uvedení JScript do souladu s ostatními JavaScriptovými motory je neuvěřitelně důležitý krok. Je škoda, že tyto podrobnosti byly v oznámeních aplikace Internet Explorer 8 do značné míry přehlíženy.