在下面描述中,IE表示Internet Explorer,FF表示Mozilla Firefox瀏覽器。
1.空白符
IE不支持v字符為空白符,會把它解析為字母v。
示例:
alert(\'v supported\'+(String.fromCharCode(11)==\'v\'));
輸出:
IE:false FF:true
Opera:true Safari:true
2.保留字
ECMA Script v3定義了25個關鍵字:break、else、new、var、case、finally、return、void、catch、for、switch、while、continue、function、this、with、default、if、throw、delete、in、try、do、instanceof、typeof。
同時還預留了31個保留字用於未來版本的功能擴展:abstract、enum、int、short、boolean、export、interface、static、byte、extends、long、super、char、final、native、synchronized、class、float、package、throws、const、goto、private、transient、debugger、implements、protected、volatile、double、import、public。
所有保留字可以作為標識符在代碼中使用,而IE僅允許下面23個保留字作為標識符使用:abstract、int、short、boolean、interface、static、byte、long、char、final、native、synchronized、float、package、throws、goto、private、transient、implements、protected、volatile、double、public。
3.字面量
IE借用C語言風格的轉義字符,設置文字的換行符,但根據ECMAScript v3標準,這種行為將引發一個未結束的字符串常量的語法錯誤。
示例:
var s=\"this is a
multiline string\";
輸出:
IE、FF、Opera、Safari:\"this is a multiline string\"
IE會把上面字符串視為單行字符串,FF、Opera、Safari與IE解析一致。
IE會忽略「」及其後面的字符。s.length將返回34(這包括在第二行中的前導空格)。
4.Arguments對像
不同引擎沒有針對函數的arguments變量名實現統一的處理方式。在IE中,arguments並沒有包含在變量所在的上下文環境中,調用eval動態執行代碼將無法改變arguments的值。
示例:
function foo{
document.write(arguments);
document.write(arguments[0]);
eval(\"arguments=10;\");
document.write(arguments);
document.write(arguments[0]);
}
foo(\"test\");
輸出:
IE:[object Object]test[object Object]test
FF:[object Object]test10undefined
Opera:testtest10undefined
Safari:[object Arguments]test10undefined
針對上面示例,如果不使用eval動態執行字符串,而是直接修改arguments變量的值:
function foo{
document.write(arguments);
document.write(arguments[0]);
arguments=10;
document.write(arguments);
document.write(arguments[0]);
}
foo(42);
則不同引擎的輸出結果如下:
IE:[object Object]4210undefined
FF:[object Object]4210undefined
Opera:424210undefined
Safari:[object Arguments]4210undefined
5.Global對像
在IE中,全局對像(Global)不能使用this進行迭代。
示例:
var__global__=this;
function invisibleToIE{
document.write(\"IE can\'t see me\");
}
__global__.visibleToIE=function{
document.write(\"IE sees me\");
}
for(func in__global__){
var f=__global__[func];
if(func.match(/visible/)){
f;
}
}
輸出:
IE:IE sees me
FF:IE sees meIE can\'t see me
Opera:IE can\'t see meIE sees me
Safari:IE can\'t see meIE sees me
在IE中,在使用delete運算符通過this指針刪除全局成員時,將會產生運行時錯誤,而在FF等瀏覽器中刪除返回false。根據標準,FF的行為是正確的,例如:
var__global__=this;
function invisibleToIE{
document.write(\"IE can』t see me\");
}
__global__.visibleToIE=function{
document.write(\"IE sees me\");
}
document.write(delete this.invisibleToIE);
輸出:
IE:runtime error(object doesn』t support this action)
FF、Opera、Safari:false
在IE中全局對像(Global)不繼承Object.prototype,即使它的類型是對象。根據JavaScript原型繼承規則,全局對像應該繼承Object.prototype,當然這些都必須依賴於實現的瀏覽器。作為內置的原型,必須遵循Object.prototype的標準方法。
var__global__=this;
document.write(typeof(__global__)+\'<br>\');
var f=[\'toString\',\'toLocaleString\',\'valueOf\',\'hasOwnProperty\',\'isPrototypeOf\',\'propertyIsEnumerable\'];
for(i=0;i<f.length;i++){
test(f[i]);
}
function test(s){
if(__global__[s]){
document.write(s+\'supported\'+\'<br>\');
}
}
輸出:
IE:
object
toString supported
FF、Opera、Safari:
object
toString supported
toLocaleString supported
valueOf supported
hasOwnProperty supported
isPrototypeOf supported
propertyIsEnumerable supported
6.初始化數組
在IE中,向數組尾部添加逗號分隔符將會增加數組的長度。IE把尾部逗號後的空白視為一個值為undefined的元素。實際上,這是一個非法解析的錯誤。
示例:
document.write([1,2,3,].length);
輸出:
IE:4
FF、Opera、Safari:3
7.函數表達式
在IE中,函數表達式中的標識符在閉包的上下文環境中是可見的,因為這種表達被視為函數聲明。
示例:
var foo=function bar(b){
if(b==true){
bar;//可以工作,因為在函數內部bar標識符是可見的
}else{
document.write(\"hello\");
}
}
foo;//可以工作,因為foo標識符指向一個函數對像
bar(false);//失敗,因為在全局環境中bar是不可見的
輸出:
IE:\"hellohello\"
FF:\"hello\"接著顯示一個語法錯誤(bar is not defined)
Opera:\"hello\"接著顯示一個引用錯誤(Reference to undefined variable:bar)
Safari:\"hello\"
IE把嵌套在函數表達式中的一個函數名稱作為一個函數聲明,這個函數聲明位於封閉的上下文環境中。在下面的示例中,IE可以向前引用x,而在其他瀏覽器中將顯示語法錯誤。
function f(x){
x;
y=function x{
document.write(\"inner called\")
};
document.write(x);
document.write(arguments[0]);
}
document.write(\"test 4\");
f(\"param\");
輸出:
IE:test 4 inner called function x{document.write(\"inner called\")}function x{document.write(\"inner called\")}
FF、Opera、Safari:test 4
再如:
function foo{
function bar{}
var x=function baz(z){
document.write(\"baz\"+z);
if(z)baz(false);
};
x(true);//合法的
bar;//合法的
baz(true);//原來是非法的,現在是合法的
}
foo;
輸出:
IE:baztruebazfalsebaztruebazfalse FF:baztruebazfalse(followed by an error-baz not defined)Opera:same as FF
FF、Opera、Safari:baztruebazfalse(followed by an error-baz not defined)
8.抽像關係比較算法
IE使用or而不是and進行字符串比較計算。
示例:
document.write(\'1<10==\'+(1<10)+\'<br>\');
document.write(\'NaN<1==\'+(NaN<1)+\'<br>\');
document.write(\'1<Infinity==\'+(1<Infinity)+\'<br>\');
document.write(\'\"10\"<1==\'+(\"10\"<1)+\'<br>\');
document.write(\'1<\"a\"==\'+(1<\"a\")+\'<br>\');
document.write(\'\"a\"<\"b\"==\'+(\"a\"<\"b\")+\'<br>\');
輸出:
IE、FF、Opera、Safari:
1<10==true
NaN<1==false
1<Infinity==true
\"10\"<1==false
1<\"a\"==false
\"a\"<\"b\"==true
9.函數體內的函數聲明
當使用函數聲明定義一個函數時,不管怎樣使用with語句修改函數的作用域,IE都會把它綁定到全局作用域上。
示例:
var v=\'value 1\';
var o={v:\'value 2\'};
function f1{
alert(\'v==\'+v);
};
with(o){
function f2{
alert(\'v==\'+v);
};
}
f1;
f2;
//修改變量的值
v=\'modified value 1\';
o.v=\'modified value 2\';
f1;
f2;
輸出:
IE、Opera:
v==value 1
v==value 1
v==modified value 1
v==modified value 1
FF、Safari:
v==value 1
v==value 2
v==modified value 1
v==modified value 2
針對上面示例,如果使用函數表達式定義f1和f2函數(代碼如下),那麼輸出結果與FF相同,說明在IE、Opera瀏覽器中with作用域會影響函數表達式,但不會影響函數聲明。
var f1=function{
alert(\'v==\'+v);
};
with(o){
var f2=function{
alert(\'v==\'+v);
};
}
10.枚舉和屬性
IE不支持通過for in語句枚舉類型的自定義屬性,這些自定義屬性通過Object.prototype進行映射進而實現繼承。
示例:
function cowboy{
this.toString=function{
return\"cowboy\";
}
this.shoot=function{
return\"bang!\";
}
}
var p=new cowboy;
document.write(\"Enumerable properties:\");
for(var i in p){
document.write(\"\",i);
}
document.write(\"<br/>cowboy propertyIsEnumerable(\"toString\"):\",p.propertyIsEn-umerable(\"toString\"));
document.write(\"<br/>cowboy hasOwnProperty(\"toString\"):\",p.hasOwnProperty(\"toString\"));
輸出:
IE:
Enumerable properties:shoot
cowboy propertyIsEnumerable(\"toString\"):false
cowboy hasOwnProperty(\"toString\"):true
FF、Opera、Safari:
Enumerable properties:toString shoot
cowboy propertyIsEnumerable(\"toString\"):true
cowboy hasOwnProperty(\"toString\"):true
11.try語句
在IE中,用於保存捕獲異常的變量在當前上下文環境是可見的,在catch子句執行完畢後此變量依然存在,但在該上下文環境被註銷後會隨之消失。
示例:
function foo{
try{
throw\"hello\";
}catch(x){
document.write(x);
}
document.write(x);//x在這裡應該是不可見的
}
foo;
輸出:
IE:hellohello
FF、Opera、Safari:
hello(然後拋出一個錯誤,x is not defined)
try語句包含自己的作用域,當拋出異常時,這個作用域是封閉的,但在IE和FF瀏覽器中可以看到一些特殊的情況。示例如下:
function foo{
this.x=11;
}
x=\"global.x\";
try{
throw foo;
}catch(e){
document.write(x)//應該輸出\"global.x\"
e;
document.write(x)//應該把x添加到e對像上,但IE和FF卻修改了全局變量x
}
document.write(x);//應該輸出\"global.x\"
輸出:
IE、FF:global.x1111
Opera、Safari:global.x11global.x
12.jion數組原型
當分隔符為undefined時,IE會使用「undefined」字符串作為分隔符來連接數組成員值。
示例:
var array=[1,2];
alert(array.join);
alert(array.join(undefined));
alert(array.join(\'-\'));
輸出:
IE:
1,2
1undefined2
1-2
FF、Opera、Safari:
1,2
1,2
1-2
13.unshift數組原型
Array.unshift方法能夠把它的參數添加到數組的起始位置,同時返回結果數組的長度,但IE在調用Array.unshift方法時的返回值為undefined。
示例:
var a=new Array(1,2,3);
var l=a.unshift;
document.write(l,\"\");
document.write(a.length,\"\");
document.write(a,\"\");
l=a.unshift(2);
document.write(l,\"\");
document.write(a.length,\"\");
document.write(a,\"\");
輸出:
IE:undefined 3 1,2,3 undefined 4 2,1,2,3
FF、Opera、Safari:
3 3 1,2,3 4 4 2,1,2,3
14.函數length屬性
Object.length、String.fromCharCode.length、String.Prototype.indexOf.length、String.Prototype.lastIndexOf.length、String.prototype.slice.length等的返回值與標準值存在差異。
❑Object.length:IE返回值為0,標準解析為1。
❑String.fromCharCode.length:IE返回值為0,標準解析為1。
❑String.prototype.indexOf.length:IE返回值為2,標準解析為1。
❑String.prototype.lastIndexOf.length:IE返回值為2,標準解析為1。
❑String.prototype.slice.length:IE和FF返回值為0,標準解析為2。
15.split字符串原型
IE可以忽略捕獲括號,FF能夠使用空字符代替undefined。
示例:
alert(\"A<B>bold</B>and<CODE>coded</CODE>\".split(/<(/)?([^<>]+)>/));
輸出:
IE:A,bold,and,coded
FF、Opera、Safari:
A,,B,bold,/,B,and,,CODE,coded,/,CODE,
16.toPrecision數值原型
如果參數的精度不確定,則IE將拋出RangeError異常。
示例:
var number=123.456;
document.write(\'number.toString==\'+number.toString+\'<br>\');
document.write(\'number==\'+number+\'<br>\');
try{
document.write(\'number.toPrecision(undefined)==\'+number.toPrecision(undefined)+\'<br>\');
}catch(e){
document.write(\'Exception thrown.\'+e.name+\':\'+e.message+\'<br>\');
}
輸出:
IE:
number.toString==123.456
number==123.456
Exception thrown.RangeError:The precision is out of range
FF、Opera、Safari:
number.toString==123.456
number==123.456
number.toPrecision(undefined)==123.456
17.valueOf日期原型
直接調用日期原型的valueOf方法,IE將返回0,而標準規定為NaN。
示例:
document.write(\'Date.prototype.valueOf==\'+Date.prototype.valueOf);
輸出:
IE:0
FF、Opera、Safari:NaN
18.Disjunction
IE將使用空字符代替undefined值。
示例:
//重寫Array.prototype.toString,使字符串包含在引號中,同時顯示undefined值
Array.prototype.toString=function{
var s=\'\';
for(var i=0;i<this.length;i++){
if(s){
s+=\',\';
}
switch(typeof this[i]){
case\'string\':
s+=\"\'\"+this[i]+\"\'\";
break;
case\'undefined\':
s+=\'undefined\';
break;
default:
s+=this[i];
break;
}
}
return\'[\'+s+\']\';
}
var a=/((a)|(ab))((c)|(bc))/.exec(\'abc\');
document.write(a);
輸出:
IE:[\'abc\',\'a\',\'a\',\'\',\'bc\',\'\',\'bc\']
FF、Opera、Safari:NaN
[\'abc\',\'a\',\'a\',undefined,\'bc\',undefined,\'bc\']
19.數列
IE不清除子表達式中重複匹配的選項。
示例:
Array.prototype.toString=function{
//執行代碼
}
var a1=/(z)((a+)?(b+)?(c))*/.exec(\'zaacbbbcac\');
var a2=/(a*)*/.exec(\'b\');
document.write(a1);
document.write(\'<br>\');
document.write(a2);
輸出:
IE:
[\'zaacbbbcac\',\'z\',\'ac\',\'a\',\'bbb\',\'c\']
[\'\',\'\']
FF、Opera、Safari:
[\'zaacbbbcac\',\'z\',\'ac\',\'a\',undefined,\'c\']
[\'\',undefined]
20.正則表達式實現
如果正則表達式的標誌中包含任何字符,那麼超出了「g」、「i」、「m」,或者這幾個字符重複都將拋出SyntaxError異常。但IE不會拋出SyntaxError或TypeError異常,它會拋出一個TypeError異常,由此可知,IE對正則表達式字符串的要求是寬鬆的,在標誌重複的情況下,不拋出任何異常。
示例:
function test(p,f){
try{
var r=new RegExp(p,f);
document.write(r.toString+\'<br>\');
}catch(e){
document.write(e.name+\':\'+e.message+\'<br>\');
}
}test(new RegExp(\'foo\'));//ok
test(new RegExp(\'foo\'),undefined);//ok
test(new RegExp(\'foo\'),\'gim\');//TypeError
test(\'foo\');//ok
test(\'foo\',undefined);//ok
test(undefined,\'gim\');//ok
test(\'foo\',\'gimgim\');//SyntaxError
test(\'foo\',\'pvl\');//SyntaxError
21.getYear日期原型
對於IE來說,Date.prototype.getYear類似於Date.prototype.getFullYear。
示例:
var d=new Date(\"10 July 2001\");
var y=d.getYear;
document.write(y+\'<br>\');
輸出:
IE:2001
FF、Opera、Safari:101
22.setYear日期原型
對於IE來說,Date.prototype.setYear類似於Date.prototype.setFullYear。
示例:
var d=new Date(+0);
d.setYear(95);
y=d.getYear;
document.write(\"setYear:\"+y+\"\");
d.setFullYear(95);
y=d.getYear;
document.write(\"setFullYear:\"+y);
輸出:
IE:setYear:95 setFullYear:95
FF、Opera、Safari:setYear:95 setFullYear:-1805