Deosebiri importante intre JavaScript (implementare W3C) si JScript (implementare Microsoft)
Cred că toţi programatorii web ştiu că există două tipuri de browsere: care se conformează cu standardele W3C (printre care Chrome, FireFox, Opera, Safari) şi care nu se conformează (în primul rând Internet Explorer sau IE).
Specificaţiile nu acoperă toate problemele apărute la implementarea limbajului ECMA-262 (altfel spus - JavaScript) în diferite medii. Pe lângă faptul că nu toate browserele se conformează cu acest standard, divergenţe apar şi în problemele asupra cărora specificaţiile nu se pronunţă în vreun fel.
Iată câteva dintre aceste divergenţe:
În mediul JavaScript din browser există două clase mari de obiecte: DOM şi non-DOM. Obiectele DOM se mai numesc Elemente şi fac parte din structura documentului HTML. Obiectele non-DOM sunt toate celelalte obiecte, toate instanţe indirecte sau directe ale Object
.
Apare o întrebare firească: Elementele (obiectele DOM) sunt instante ale Object sau nu?
Raspunsul la această întrebare depinde de mediul ales: IE sau non-IE. Elementele se comporta in toate privintele ca niste obiecte obişnuite (non-DOM), având şi ceva proprietăţi specifice. Deci logic ar fi să fie instanţe ale clasei Object.
Deci, în IE elementele nu sunt instanţe ale Object
, şi în general nu sunt instanţe ale căreiva clase în sensul că elem instanceof X === false
pentru orice element si orice clasa
-
function x() {};
alert(x.name); // expected 'x', got undefined
Atributul "name
" al obiectelor de tip Function nu este un standart ECMA-262, însă a fost introdus de către Mozilla şi acceptat de către toate browserele majore, desigur cu excepţia IE.
-
var y = function z(){};
alert(typeof z); // expected undefined, got 'function'
În toate browserele typeof z == undefined
, iar in IE typeof z == 'function'
.
Acesta e un subiect mai vast. Expresia de mai sus se numește funcție expresie cu nume (named function expression).
Iată un articol care explică în detalii această problemă și altele similare: NFE.
-
var y = function z(){ return z.proprietate; };
y.proprietate = 'test';
alert(z()); // Expected 'text', got undefined in IE
Cauza acestui bug e aceeași ca și în exemplul precedent, dar efectul e diferit. În IE y != z, adică avem două obiecte diferite în memorie. Acest fapt poate provoca probleme semnificative în anumite situații.
-
var s = 'abcd';
alert(s[1]); // expected 'b', got undefined
În mod normal în toate browserele s[1] == 'b'
, cu exceptia IE până la versiunea 8, unde s[1] === undefined
.
-
var a = Array.prototype.slice('abcd');
alert(a);
Aceasta este o metodă eficientă de obţinere a obiectelor de tip Array
din orice obiect ce conţine proprietatea 'length'
(de ex. String
).
Cu părere de rău nici în IE8 aceasta nu e o metodă în cazul String
. În aces caz recomand 'abcd'.split('');
-
var a = [1, 2, 3, 4, 5];
try{ alert(a.indexOf()); } // W3C
catch(e) { alert(e.description); } // IE
Obiectele de tip String
au metoda indexOf
. Însă cele de tip Array
în IE nu au, deoarece IE foloseşte o versiune mai veche de JScript (1.3, ECMA-262 3rd edition).
-
var x = 10;
function a(){ return x; try{}catch(x){} };
alert(a()); // Expected 10, got undefined
În browserele W3C a() === 10, însă nu şi în IE... Pentru simplul fapt că există catch(x), variabila x este redeclarata in scopul functiei a(), ca şi cum am avea declaraţia: function a(){ var x; return x; };
-
window.b = 1;
var b = b || 2;
Nu am cercetat până la urma această situaţie, dar în unele imprejurări b == 2, deşi ar trebui sa fie 1.
Am avut o situaţie în care prima instrucţiune se efectua într-un fişier JS, iar a doua în alt fisier JS şi am obţinut efectul nedorit (în IE).
Recoman să cercetați tabelul de compatibilitate ES5