前几日,和朋友解说javascript预解析机制的时候,给了下面的示例代码:
var a = 1; function a(){ alert(1111); }; alert(a);
var a ; function a(){ alert(1111); }; a = 1; alert(a);
如果有疑问的同学可以参考ECMA文档,下面这个链接我网上搜的,不想去求证,只想理解机制的同学可以参考下:http://www.zhufengpeixun.com/jishujiangtang/javascriptjiangtang/2011-01-16/512.html
第一部分的代码,在FF、chrome、IE下运行都是显示1,没啥疑问,而我朋友在FireBug console下运行的时候,确弹出函数代码,也就是:
function a(){
alert(1111);
};
隐约记得半年前在网上看到一个老外的帖子说FireBug console是用eval执行输入的代码的,不过具体忘记了,最近去搜也没搜到。在这里个人推测下,FireBug是按语句一条一条eval的, 也就是上面代码变为:
eval('var a = 1'); eval('function a(){alert(1111);}'); eval('alert(a)');而eval是将执行的语句加入到最近作用域中,按上述的方式,每条语句都是立即执行,自然就是弹出函数代码了。自此,FireBug的解析问题也许有一个推测的答案,希望有更权威的文献论证。
-------------------------------------------------华丽分割线-----------------------------------------------------------------
接着是FireFox下的Bug,同样是类似的代码,今天不知脑抽怎么的,居然会用这样的代码去测试,居然会测试出FF和IE8以及Chrome的不同执行结果,先不废话,代码如下:
{ var a = 1; function a(){ alert(1111); } alert(a); }是的,你没看错,只是在最开始的代码上加入了两个大括号而已,JS是函数级作用域,以上从语法角度说,依然是在全局下运行,依然是应该弹出1,在Chrome14和IE8下运行也是如此,可是在FireFox6下运行,居然弹出的是函数代码,坑爹啊是不,弹出的是函数代码啊。。 蛋都碎了。。 这又是个什么情况?
推测1: 难道FireFox的JS引擎对花括号内的语句是一条一条解析的,而没有经过预解析过程?以下代码似乎推翻了这个推测:
if(0){ var a = 1; function a(){ alert(1111); } alert(a); } alert(a)
上述代码在chrome和IE8下,弹出的是函数代码,说明什么了? 不是太理解? 再加句,执行以下代码:
if(0){ var a = 1; function a(){ alert(1111); } alert(a); } alert(a) a();
于是有了推测2:
FF对JS语句的var关键字和其他浏览器一样,都是优先扫描,但是对语句块(花括号)内的function声明有着不同的处理,IE8和Chrome对语句块内的function声明同样是预解析处理, 而FF对语句块内的function声明则当作函数表达式,即上述代码中的函数声明在FF中翻译为: var a = function(){alert(1111);}; 这样做似乎可以对JS进行优化,比如上述的if语句,条件为假,内部代码理应不被执行,而在IE8和Chrome下确发现a居然是个函数,对未理解JS预解析机制的同学会造成莫大的迷惑。
至此,似乎FireFox下的Bug也有了一个似乎合理的解释。不过同样的,这两个解释都是推测,还是希望有权威的资料出来。