=波波日志 > JavaScript/Ajax > javascript执行顺序与作用域=

[转]javascript执行顺序与作用域

关于JS变量声明的小细节

对于从未声明过的对象,如果尝试给它赋值,会隐式的将它声明为全局对象。比如:



+展开
-JavaScript
(function() {

  s = 'abc';

})();

alert(s); //会弹出 abc




如果尝试读一个未声明的对象,JS会报错。比如:



alert(a); //不会弹出对话框,会报错



这个结论是犀牛书中所写。但是有意思的是,在IE里,如果尝试读一个未声明的对象,并不会报错,当然也不会继续执行JS。这点其实挺要命,不执行也不告诉你为什么。



但这个结论是铁律,所以如下的写法是经常容易犯的错误:

+展开
-JavaScript
 

if(!a) {

    //do sth. ...

}




这样写有时候的初衷是:如果变量a不存在,就执行里面的语句。但如果a未定义,在Firefox中会报错;在IE里不会报错,但也不会执行以后的所有语句。



所以该如何探测一个变量是否被定义呢?一个巧妙的办法是:


+展开
-JavaScript

if(!window.a) {

    //do sth. ...

}



这个方法其实很奇妙,因为读一个未声明的变量,会报错;但读一个未声明的属性,就不会报错。天晓得JS为啥规定这样奇怪的语法。



但是这样的方法只适用与全局变量。若是某个函数里的局部变量,还是用typeof去判断吧:



+展开
-JavaScript
if(typeof a == 'undefined') {

    //do sth. ...

}




所以,结论就是,养成习惯,不要在变量未定义之前使用它。



接下来再看一个例子:



+展开
-JavaScript
var a = "I'm out";

(function() {

    alert(a);

    var a = "I'm in";

})();




好,提问,运行这段代码,会弹出什么文字?



回答一:弹出“I’m out”。错。JS没有块级作用域,无论var语句在何处,在整个函数体内它都是有定义的。



回答二:
弹出“I’m in”。错。请再重新看上面那句话,它只是在整个函数体内有定义,但只有在被赋值之后才会有值。



正确答案是:
“undefined”。是不是很晕?自己试试看吧。



总之,再重复一遍之前的结论:不要在变量未定义之前使用它。



最后介绍一个我也搞不明白的问题:



在HTML文档里写上这段代码:



+展开
-HTML
<script type="text/javascript">

    window['a'] = 'Hi';

</script> 

<script type="text/javascript" src="out.js"></script> 

<script type="text/javascript">

    alert(a);

</script> 




然后在out.js里写上这句:


+展开
-JavaScript

 if(false) {

     var a = 'Hello';

 }



然后用FF和IE6分别运行,看看你得到什么。



在FF里会弹出“Hi”,但是在IE6中,会得到“undefined”。



很神奇吧?按语法,无论如何,a都不可能是undefined。但是IE6里就会。



如果把两个语句都写在同一个文件里,就不会有这个情况。

如果把out.js里改成window.a,或者把前一个改成var a,也不会有这个情况。

如果把out.js里的var a移到if语句之外,或是把if的条件改为true,也不会有这个情况。



这个bug其实危害性很大。所以呢,只能给自己定一个好习惯,那就是不要在条件语句中声明变量,虽然这么做,语法上并不禁止。




/*******************************************************************/
TJ注明:
1、作用域不同产生的效果也不一样,在同一个function中,js会先在function中查找是否有变量status的声明,如有则以function域中的为准,但是也有使用的先后顺序问题。
2、同时在同一作用域中变量的赋值的时候,函数的赋值要快于一般常量的赋值。

如:
+展开
-JavaScript
function b(){
      alert(a);
      var a = '常量';

      function a(){}
    }

此时alert出来的将是:'function a(){}';
如:
+展开
-JavaScript
function b(){
      alert(a);
      var a = '常量';
    }

此时alert出来的将是:'undefined',上两个说明赋值顺序和执行顺序的问题。
如:var a = '变量';
+展开
-JavaScript
    function b(){
      alert(a);
      var a = '常量';
    }

此时alert出来的也将是:'undefined',这个可以说明作用域的问题。

来源:http://wenku.baidu.com/view/dafd0920af45b307e8719792.html


类别:JavaScript/Ajax 作者:转载 日期:2011-08-05 【评论:0】 
 
暂时没有评论!
发表留言
  • *昵称:
  • 头像:
  • 电子邮件: [留下您的邮件,方便管理员回复您。]
  • 个人网站: *验证码:
声明:本网站尊重并保护知识产权,根据《信息网络传播权保护条例》,如果我们转载或引用的作品侵犯了您的权利,请通知我们,我们会及时删除!
Powered by showbo,©2012,桂ICP备05005887号 京公网安备1101055090