日期:2014-05-17  浏览次数:20929 次

【分享】Firefox中神奇的JS引擎逻辑判断代码优化
Firefox 结束了IE长期的垄断地位,抱着地球的火狐狸,给了我们很多惊喜。Firefox3.6的JS引擎TraceMonkey是从Firefox原来的 JavaScript引擎SpiderMonkey进化而来,由于采用了一种新的实时编译器技术,可以将JavaScript的性能提升很多。而且 TraceMonkey也不知不觉的对你的代码进行了一些优化。这些优化,理论上讲可以是代码的执行提速,但,也可能会引起兼容性的问题。比如,今天要给大家分享的这个问题就是这样一个,,奇怪的问题。

先看一段代码:
JScript code
function testFN(){
   if ( true ) {
       function A(){alert('A')}
   }else{
       function A(){alert('B')}
   }
   A();
}
先猜测一下,如果执行testFN(),应该弹出 “A” 还是 “B”?还有,这段代码有问题吗?
很显然,从语法上讲,没有任何的问题,但是从逻辑上讲,是不是感觉有点儿多此一举呢?IF判断后的条件是 true,也就是说,判断语句永远不会执行else分支。所以,从逻辑上讲,上面的代码应该等价于:
JScript code
function testFN(){
  function A(){alert('A')}
  A();
}

真的是这样吗?

打开你的浏览器,试一下我们没有精简过的代码会弹出”A” 还是 “B”。
经过测试:只有Firefox会弹出”A”,其他浏览器都会弹出”B”。

看来,在其他浏览器中,不能按照逻辑上的等价来简化上面的代码,为什么呢?

JS语法解释器在执行一段JS代码时,会将其上下文范围内的函数声明提到最前端。类似如下代码:
JScript code
function testFN(){
   var bl = true;
   function A(){alert('A')}
   function A(){alert('B')}
   if ( bl) { }else{ }
   A();
}

所以,if分支里的 function A(){alert('A')} 会被 else 分支里的 function A(){alert('B')} 覆盖,在执行函数时运行的是最后定义内容,因此会提示 “B”。

那在Firefox里,为什么会弹出 “A”呢?
我们把定义好的函数打印出来:
JScript code
function testFN(){
   if ( true ) {
       function A(){alert('A')}
   }else{
       function A(){alert('B')}
   }
   A();
}
document.write(testFN);
打印在页面上的结果:

Firefox很出乎人意料的,给出了这种结果。

修改一下代码:
JScript code
function testFN(){
   if ( 1===1) {
       function A(){alert('A')}
   }else{
       function A(){alert('B')}
   }
   A();
}
document.write(testFN);

这时候,所有浏览器中的输出都是:
function testFN() { if (1 === 1) { function A() { alert("A"); } } else { function A() { alert("B"); } } A(); }

那么这时候,执行testFN 会不会在所有浏览器中都输出 “B”呢?
经测试,Firefox中还是一如既往的 “A”。看来,Firefox貌似很智能的,将代码优化了。

要解决这个问题,其实很简单:
JScript code
function testFN(){
   var A;
   if ( 1===1) {
       A=function(){alert('A')}
   }else{
       A=function(){alert('B')}
   }
   A();
}



更多兼容性问题:【分享】浏览器兼容性问题目录

------解决方案--------------------
很有深度
------解决方案--------------------
从来没注意过。。。
------解决方案--------------------
给楼主补充个,其实FF的蜘蛛猴子对代码优化不止这些,比如:
Java code

function aa(){return 2+4}
alert(aa)

------解决方案--------------------
探讨

引用:

给楼主补充个,其实FF的蜘蛛猴子对代码优化不止这些,比如:
Java code

function aa(){return 2+4}
alert(aa)


函数内直接优化成6了~~
即使这样,猴子蜘蛛还是没V8快吧