http://bbs.51js.com/viewthread.php?tid=70499&highlight=%2Bwintervar预解析

解决方案 »

  1.   


    <script type="text/javascript">
    var   str='hello'; //这里定义了一个全局变量 str
    function   say(){ 
    alert(str);   //这里他找str应该是先找是否存在局部变量str 事实是存在的 但是在这里他还没有值 那就是undefined 
    var str = "hi";  //这里定义了一个局部变量str  如果把这句调到alert(str)前则可以得到hi

    say(); 
    </script>
      

  2.   

    我以前做过测试过,一个JS里,调用函数语句先于函数,也正常执行,所以就知道是先定义所有函数。然后再顺序执行其它语句。例如:
    a()
    function a(){ }
    这样是正常的,因为函数function a(){}先定义,也就是mingxuan3000说的预编译,但不是对var预编译。例如:
    a()
    var a=function(){}
    这样就出错了,因为var a=function(){}这种形式不会被优先处理,也就是不同于function a(){},专业术语我不懂哈。然后就是全局变量与函数内部变量的问题了,一个全局变量如果被某一个函数内部用var 重新定义,这个全局变量就变回局部变量,所以在函数内部对变量赋值时也得注意是否应该用var去定义。以下两个是解释一个JS文件载入和和处理的顺序,不太懂专业术语,专家们别砸我。say()
    var str='hello';
    function say(){ alert(str) }var str='hello';
    say()
    function say(){ alert(str) }
      

  3.   

    如图所示,当在函数b中访问一个变量的时候,搜索顺序是先搜索自身的活动对象,如果存在则返回,如果不存在将继续搜索函数a的活动对象,依次查找,直到找到为止。如果整个作用域链上都无法找到,则返回undefined。如果函数b存在prototype原型对象,则在查找完自身的活动对象后先查找自身的原型对象,再继续查找。这就是Javascript中的变量查找机制。
      

  4.   

    没搞清楚javascript的变量申明原则.
      

  5.   

    <script>
    var   str='hello';
    function   say(){
    alert(str);
    var   str="hi";//屏蔽全局變量str='hello'
    }
    say();
    </script>
    如果局部變量與全局變量同名,就會把全局屏蔽掉。
    <script>
    var   str='hello';
    function   say(){
    alert(str);
    var   str="hi";//屏蔽全局變量str='hello'
    }
    say();
    alert(str);//此處會alert出hello
    </script>
      

  6.   

    俺觉得用“风之石”讲滴JS变量查找机制就完全可以解释清楚!
    var str='hello';
    function say()
    {
        alert(str);
        var str="hi";
    }
    say();alert(str)首先在say函数内部查找变量名str,结果在调用点后面找到了var str="hi";
    var是js的变量声明关键字,因此alert(str)中的str被判定为undefined!
    此时查找已经over了,根本没有触及全局str!
    如果在say()调用之后,再次调用alert(str),那么输出的还是hello!俺也明白多了,那个var预编译讲滴太玄乎,俺很不喜欢,哈感谢“风之石”图文并茂滴解释!给您加50,可惜俺不是楼主,哈!
      

  7.   

    在函数内部用var对全局变量进行重新声明,我还一直以为直接把全局变量改写成函数内部变量,原来只是在函数内部屏蔽全局变量,函数返回后全局变量依然存在,如果函数里的变量不用var声明,会直接当成是全局变量,又学习了。然后对那个var预编译就比较难理解,倒是听楼上所有的说法,明白了。但人性方面还是无法接受JS那个变量查找机制。
      

  8.   

    To ChDw讨论原理而已,实际编码这么写会死人滴(要么自杀、要么被杀),哈
      

  9.   

    To  yixianggao 应该是要去杀人或者被人杀
      

  10.   

    To yixianggao :风之石只是给出了变量查找机制,并不能解释楼主的问题。同意铭轩的“var 预解析”说法。
    如果你仅从风之石的变量查找机制来解释这个问题就理解错了这个问题的真正含义。请用脚本调试器单步跟综看一下。
    var str = 'hello'; 
    function   say(){ 
      alert(str);       // 这里设断点,可以看到有两个undefined的值,str和str2。
      var str = "hi"; 
      var str2 = "test";

    say(); 
    注意这个顺序:
    脚本是先预先解析变量声明,再从上往下执行。
    而不是遇到变量后再往外找它是否被定义了。
      

  11.   

    <script> 
    var   str='hello'; 
    function   say(){ 
    var str;
    alert(str); 
    str="hi"; 

    say(); 
    </script> 
    实际是就是这样的运行过程
    有一个跟这个类似的function问题
    貌似叫预编译alert(a)
    alert(b)var a = function(){}
    function b(){}实际上是function b(){}
    var aalert(a)
    alert(b)a = function(){}风之石 的图貌似是闭包的东西
      

  12.   

    <script> 
    // var   str='hello'; 
    function   say(){ 
    alert(this.str); 
    var   str="hi"; 

    say(); 
    </script>这是变量域
    函数体内声明的变量都为局部变量,,,无论先后
    this.引用全局window
      

  13.   

    多谢0009滴指正!var预编译虽然没有明确标志,但是确实存在,主要是用于确定每个变量作用域!var str='hello'; // 这个 str 是全局变量。
    function say()
    {
        alert(str); // undefined,这个 str 是局部变量,应该是在var预编译时确定滴!但未赋值!
        str = "123"; // 尽管声明在后面,但这个 str 是局部变量。
        alert(str); // 123
        var str="hi"; // 声明 function 内部的 str 。
    }
    say();
    alert(str); // 是 hello 而不是 123
      

  14.   

    简单的说就是function f() {
    alert(a);
    var a = 'a';
    }等于function f() {
    var a;
    alert(a);
    a = 'a';
    }
      

  15.   

    24楼。。
    先不要测试,你考虑下面两种情况分别是什么结果呢?
    1:
    function   f()   { 
    alert(a); 
    var   a   =   'a'; 
    } f();function   f()   { 
    var   a=new String; 
    alert(a); 
    a   =   'a'; 
    }
    f();
    2:
    function   f()   { 
    alert(a); 
    var   a   =   'a'; 
    } f();function   ff()   { 
    var   a=new String; 
    alert(a); 
    a   =   'a'; 
    }
    ff();
      

  16.   

    看了所有的解释,明白了var预编译的含义,难怪以前经常用if(bb==null){var bb="12" }不会发生错误,原来是JS预先把所有有var声明的预先进行var bb这样的形式,只是我们没有看到。现在能理解了。19楼的cloudgamer和24楼的willko举的例子讲得很明白了,又学习了。