Javascript的“预解析”

1. Javascript在执行前会进行类似“预解析”的操作:首先会创建一个当前执行环境下的活动对象,并将那些用var申明的变量设置为活动对象的属性,但是此时这些变量的赋值都是undefined,并将那些以function定义的函数也添加为活动对象的属性,而且它们的值正是函数的定义。
 
2.在解释执行阶段,遇到变量需要解析时,会首先从当前执行环境的活动对象中查找,如果没有找到而且该执行环境的拥有者有prototype属性时则会从prototype链中查找,否则将会按照作用域链查找。遇到var a = …这样的语句时会给相应的变量进行赋值(注意:变量的赋值是在解释执行阶段完成的,如果在这之前使用变量,它的值会是undefined)。

例子1:

function handle(){
alert(arg1);
} ;
handle();
var arg1 = 20;

结果是:undefined。因为在解释到 var arg1 = 20; 这句之前就打印了arg1的值,此时尚未给arg1赋值。

例子2:

handle();
var handle = function(){
alert(20);
};

结果:handle is not a function. 因为在执行handle()这句时,并没有给handle赋值-函数定义。如果改为:

handle();
var handle = function handle (){
alert(20);
};

在IE下会弹出对话框,因为它将var handle…这句同时解释为函数定义,而函数定义在预编译时就应经有值,所以可以执行。但在FF中,依然只解释为一个变量申明,知道执行到这一句时才会赋值。

正因为如此应避免在变量被初始化之前使用变量。

3. try/catch的例外

有如下代码:

try{
alert(var1);
alert(varFun);
alert(Fun);
var var1 = 1;
var varFun = function(){};
function Fun(){alert(1);}
}
catch(e){
function Fun(){alert(2);}
}

以上代码在IE、Chrome中的运行结果是undefined、undefined和fuction(){alert(2);},而在Firefox中的结果是undefined、undefined和“Fun未定义”报错。还不太清楚Firefox对于try/catch的“预解析”是怎么处理的。

You can follow any responses to this entry through the RSS 2.0 feed. You can leave a response, or trackback from your own site.

3 Comments »

 
  • […] 以上代码片段是在全局作用域下定义的,对于第一个例子,Javascript在预解析的时候已经将变量a的声明添加到了活动对象中(具体可参考Javascript的“预解析),于是在运行时 "a" in window 为true。 […]

  • […]         with(obj){ p = 1}; 代码块的行为实际上是修改了代码块中的执行环境,将obj放在了其作用域链的最前端,在with代码块中访问非局部变量是都是先从obj上开始查找,如果没有再依次按作用域链向上查找,因此使用with相当于增加了作用域链长度。而每次查找作用域链都是要消耗时间的,过长的作用域链会导致查找性能下降。 […]

  • supersha 说:

    try/catch的例外 的例子中,chrome和ie输出的结果不同。

 

Leave a Reply

XHTML: You can use these tags: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong> <pre lang="" line="" escaped="">