有下面几段段函数
1.var a = 123;
function test() {
  document.write(a);
}
test()
2.var a = 123;
function test() {
  document.write(a);
  var a = 345;
}
test();
3.a = 123;
function test() {
  document.write(a);
  a = 345;
}
test();
4.a = 123;
function test() {
  document.write(a);
  var a = 345;
}
test();
这4段代码分别执行出的结果是
1. 123
2. undefined
3. 123
4. undefined对于第2段代码相对于第1段就加了句 var a = 345;
为什么值就是undefined?照理来说不是顺序执行的么,第2段应该在执行 document.write(a); 这个的时候还没有var a = 345;这句的,为什么却又偏偏起了作用了,难道 解释器先找到 var 这个再去执行代码?

解决方案 »

  1.   

    是命名冲突了!a = 123;
    function test() 
    {
      alert(window.a);
      var a = 345;
    }
    test();这样可以正确弹出123!test();调用方法前,test 方法虽然没有执行,但是浏览器对他做了解析!
    function test() {
      document.write(a);
      var a = 345;
    }
    你在函数内部 声明了一个变量a,所以这里会执行 函数内部的变量a,而不是全局的变量a!
    而执行 document.write(a);时,局部变量a 还没有声明所以是 undefined!
    1和3,你没有在函数内声明变量,是使用的全局变量!当然是允许的!
      

  2.   

    顶!
    这个主要就是js中变量的规则:
    全局变量,局部变量!
    js不是java,它在文件加载时就已经把变量加载了!
      

  3.   

    或者看看这个
    var a = 123;
    function test() {
      document.write(a);
      a = 345;
      document.write(a);
    }
    test();
      

  4.   

    js在执行的时候会把当前的作用域的变量全部提前并设置在为 undefined我去面试都不知道遇到过多少次了baidu 搜索 javascript 预编译
      

  5.   

    加补充下
    JS 预编译时变量为undefined
      

  6.   

    本文主要是讲预编译。1. undefined
    当需要判断一个变量是否为 undefined 时,直接用
    Js代码   1. alert(om == undefined);  alert(om == undefined);
    可能出错。因为 JS 如果引用未声明的变量,那么会出现JS错误,在上述例子中,如果 om 未曾声明,就会报 JS 错误。因此判断一个变量是 undefined,最好用这种方法
    Js代码   1. alert( typeof om == 'undefined' );  alert(typeof om == 'undefined');2. JS 中没有块作用域,在函数中声明的变量在整个函数中都可用(无论是在函数开头处声明还是末尾处声明),如
    Js代码   1. function () {   
       2.       alert(om);        // 显示 undefined   
       3.       var om = 'abc' ;   
       4.       alert(om);        // 显示 abc   
       5. }  function() {
            alert(om);       // 显示 undefined
            var om = 'abc';
            alert(om);       // 显示 abc
       }3. JS 在函数执行前将整个函数的变量进行声明,无论这个变量的声明语句有没有机会执行,如
    Js代码   1. function () {   
       2.     alert(om);       // 显示 undefined   
       3.     if ( false ) {               
       4.         var om = 'abc' ;      // 此处声明没有机会执行   
       5.     }   
       6. }  ======================================================================今天工作需要,搜索下JS面试题,看到一个题目,大约是这样的
    Js代码   1. <script>   
       2.     var x = 1, y = z = 0;   
       3.     function add(n) {   
       4.         n = n+1;   
       5.   }   
       6.   
       7.     y = add(x);   
       8.       
       9.     function add(n) {   
      10.        n = n + 3;   
      11.     }   
      12.   
      13.     z = add(x);   
      14. </script>  <script>
       var x = 1, y = z = 0;
       function add(n) {
           n = n+1;
      }   y = add(x);
       
       function add(n) {
          n = n + 3;
       }   z = add(x);
    </script>问执行完毕后 x, y, z 的值分别是多少?仔细看的人马上就知道了, x, y 和 z 分别是 1, undefined 和 undefined。不过,如果将两个 add 函数修改一下,题目变为
    Js代码   1. <script>   
       2.     var x = 1, y = z = 0;   
       3.     function add(n) {   
       4.        return n = n+1;   
       5.   }   
       6.   
       7.     y = add(x);   
       8.       
       9.     function add(n) {   
      10.        return n = n + 3;   
      11.     }   
      12.   
      13.     z = add(x);   
      14. </script>  <script>
       var x = 1, y = z = 0;
       function add(n) {
          return n = n+1;
      }   y = add(x);
       
       function add(n) {
          return n = n + 3;
       }   z = add(x);
    </script>
    那么这时 y 和 z 分别是什么呢?我马上想到是 2 和 4,不过结果却是 4 和 4。
    这说明,在第一次调用 add 函数之前,第二个 add 函数已经覆盖了第一个 add 函数。原来,这是 JS 解释器的"预编译",JS 解析器在执行语句前会将函数声明和变量定义进行"预编译",而这个"预编译",并非一个页面一个页面地"预编译",而是一段一段地预编译,所谓的段就是一个 <script> 块。且看下面的代码
    Js代码   1. <script>   
       2.     function add(n) {   
       3.        return n = n+1;   
       4.   }   
       5.     alert(add(1));   
       6. </script>   
       7.   
       8. <script>   
       9.     function add(n) {   
      10.        return n = n+3;   
      11.   }   
      12.     alert(add(1));   
      13. </script>  <script>
       function add(n) {
          return n = n+1;
      }
       alert(add(1));
    </script><script>
       function add(n) {
          return n = n+3;
      }
       alert(add(1));
    </script>会分别弹出 2 和 4。那么,将上面的题目再变换一下,如下
    Js代码   1. <script>   
       2.     alert( typeof addA);   
       3.     addA();   
       4.     function addA() {   
       5.        alert( "A executed!" );   
       6.     };   
       7. </script>   
       8. <script>   
       9.     alert( typeof addB);   
      10.     addB();   
      11.     var addB = function () {   
      12.       alert( "B executed!" );   
      13.     };   
      14. </script>  <script>
       alert(typeof addA);
       addA();
       function addA() {
          alert("A executed!");
       };
    </script>
    <script>
       alert(typeof addB);
       addB();
       var addB = function() {
         alert("B executed!");
       };
    </script>执行结果是什么呢? 按照前面的知识,第一个 <script> 块执行正常,结果就是弹出 "function" 和 "A executed!" 的对话框。
    那么第二个 <script> 块呢? 执行结果是弹出 "undefined" 的对话框后报 JS 错误,说 addB 不是一个 function。
    有点出乎意料?呵呵,其实第一个 script 块中的 addA 一句是函数声明,当然进行了"预编译",但是第二个 script 块中的 addB 一句并非函数声明。只不过在执行这段 <script> 之前对变量进行了"预声明",因此一开始变量addB是存在的,只不过是 undefined 的(可参看http://eclipse07.javaeye.com/admin/blogs/484566 )。因此执行结果便如上面所示。将题目再变化下,如下
    Js代码   1. <script>   
       2.     alert( typeof addB);   
       3.     addB();   
       4.     var addB = function addB() {   
       5.       alert( "B executed!" );   
       6.     };   
       7. </script>  <script>
       alert(typeof addB);
       addB();
       var addB = function addB() {
         alert("B executed!");
       };
    </script>
    执行结果如何呢?
    在 ff 下执行,与上面执行结果一样。打住,且在 IE6 下执行看看如何。
    结果是弹出 "function" 和 "B executed!",一切正常。
    Google 了一下,有人说这是 IE 的 BUG。那么,请看下面的代码
    Js代码   1. <script>   
       2.     alert( typeof addB);   
       3.     var addB = "variable" ;   
       4.     function addB() {   
       5.         alert( "function addB" );   
       6.     }   
       7.     alert(addB);   
       8. </script>  <script>
       alert(typeof addB);
       var addB = "variable";
       function addB() {
           alert("function addB");
       }
       alert(addB);
    </script>
    执行结果是"function"和"variable"。
    JS解析器先预定义了 addB 变量为 undefined, 但是 addB 函数覆盖了此变量,因此一开始执行结果是 function,然后 addB 被赋值为 "variable",因此最后执行结果是 "variable",上面的代码即使变为
    Js代码   1. <script>   
       2.     alert( typeof addB);   
       3.     function addB() {   
       4.         alert( "function addB" );   
       5.     }   
       6.     var addB = "variable" ;   
       7.     alert(addB);   
       8. </script>  <script>
       alert(typeof addB);
       function addB() {
           alert("function addB");
       }
       var addB = "variable";
       alert(addB);
    </script>
    结果也一样,这说明JS解析器先预声明变量,再预定义函数 。
    小结一下:JS 在执行前会进行类似"预编译"的操作,而且先预定义变量再预定义函数。