原文:JS的预编译和执行顺序 详析

最近在复习javascript的事件处理时发现了一个问题,然后也是我来写javascript的预编译和执行顺序的问题

 
  代码:
 
复制代码
代码一
  <head>
    <title>事件处理</title>
    <meta http-equiv="content-type" content="text/html;charset=utf-8"/>
    <script type='text/javascript'>
        //页面在在完成加载后
        window.onload=function(){
            var input=document.getElementById('button');
            var p=document.getElementById('p');
            var i=1;
            while(input){
                input.onclick=function(){
                    p.innerHTML+='<br />('+ i +') '+this.nodeName;
                }
                i++;
                input=input.parentNode;
            }
        }
    </script>
  </head>
  <body>
    <div>
    <input type='button' value='Event事件' id='button' />
    <p id='p'>事件捕获的顺序:</p>
    </div>
  </body>
</html>
复制代码
 显示的结果为:
 
                      
 
当我更改了代码中红色的部分后得到的结果又不相同:
 
复制代码
代码二
<html>
  <head>
    <title>事件处理</title>
    <meta http-equiv="content-type" content="text/html;charset=utf-8"/>
    <script type='text/javascript'>
        //页面在在完成加载后
        window.onload=function(){
            var input=document.getElementById('button');
            var p=document.getElementById('p');
            var i=1;
            while(input){
                input.onclick=function(){
                    p.innerHTML+='<br />('+ i++ +') '+this.nodeName;
                }
                input=input.parentNode;
            }
        }
    </script>
  </head>
  <body>
    <div>
    <input type='button' value='Event事件' id='button' />
    <p id='p'>事件捕获的顺序:</p>
    </div>
  </body>
</html>
复制代码
得到的结果为:
 
             
 
  得出这两种不同的结果那是因为javascript代码在运行时有预编译和执行两个阶段,在预编译阶段会对函数和变量进行处理,对所有的声明变量会赋值为underfined,对所有的声明函数也会赋值为函数的定义。
 
  下面我们来测试javascript的执行过程
 
  1.javascript代码执行顺序时按照脚本标签<script>出现的顺序来确定的,浏览下面页面你会发现代码是按从上到下的顺序执行的
 
复制代码
<script type='text/javascript'>
    alert('one');
  </script>
  <script type='text/javascript'>
  alert('two');
  </script>
  <script type='text/javascript'>
  alert('three');
  </script>
复制代码
   2. 因为变量在预编译时被赋予一个undefined初值,所以下面代码中,第一个变量name在代码中没有被赋值,所有就延用undefined这个值,下面的name被赋予了Jude,所以第二次输出的是Jude这个字符。
 
<script type='text/javascript'>
    alert(name);                    //显示undefined
    var name='Jude';
    alert(name);                    //显示Jude
</script>
  3.从如下结果中我们知道先是连续两次输出Hello Wrold!,最后连续两次输出test,得出这样的结果是因为javascript并非是完全按照顺序执行的,而是在执行之前先进行一个预编译,预编译 时声明式函数被提取出来,优先执行,而且相同的函数会进行覆盖,再执行赋值式函数。
 
复制代码
<script type='text/javascript'>
    test();                    //输出Hello World!
    function test(){       
        alert('hello');     //声明式函数
    }
    test();                    //输出Hello World!
 
    var test=function(){    //赋值式函数
        alert('test');
    }
    test();                    //输出test
    function test(){      //声明式函数
        alert('Hello World!');
    }
    test();                    //输出test
</script>
复制代码
  4.下面代码显示显示hello,再显示hello world!,这是因为javascript中的给个代码块是相互独立的,当脚本遇到第一个<script>标签时,则javascript 解析器会等这个代码块加载完成后,先对它进行预编译,然后再执行之,然后javascript解析器准备解析下一个代码块,由于javascript是按 块执行的,所有一个javascript调用下一个块的函数或者变量时,会出现错误
 
复制代码
<script type='text/javascript'>
    function test(){
        alert('hello');                //显示hello
    }
    test()
</script>
<script type='text/javascript'>
    function test(){
        alert('hello world!');        //显示hello world!
    }
    test()
</script>
复制代码
  5.虽然javascript是按块执行的,但不同的块却属于相同的全局作用域,不同的块的变量和函数式可以相互使用的,也就是某个块可以使用前面块的变量和函数,却不可以使用它之后的块的变量和函数
 
复制代码
<script type='text/javascript'>
    alert(name);                    //显示undefined
    var name='Jude';
    function test(){
        alert('hello');
    }
    fun();                            //不能调用下一个块的函数
</script>
<script type='text/javascript'>
    alert(name);                    //可以调用上一个块的变量,显示Jude
    test();                            //可以调用上一个块的函数,显示hello
    function fun(){
        alert('fun');
    }
</script>
复制代码
  6.javascript在预编译阶段是以函数来划分作用域的,然后再通过var 声明的变量来与声明函数开辟内存空间,对var变量赋初值undefined。在执行阶段再根据作用域来嘴变量进行赋值.
 
  第一个代码块中函数里面的变量a是局部变量,因为a在函数内重新用var定义,所以输出undefined,而变量b是全局变量,因为在函数内没有用var重新声明b,所以在给变量b赋值时到全局变量中找全局变量b的值,所以输出的是b.
 
  第二个代码块中的函数内都重新声明了变量a和b,所以他们都是函数内的局部变量,所以都输出undefined。
 
复制代码
<script type='text/javascript'>
    var a='a';
    var b='b';
    function test(){
        alert(a);                //显示undefined
        alert(b);                //显示b
        var a='test';
    }
    test();
</script>
<script type='text/javascript'>
    var a='a';                    
    var b='b';                    
    function test(){
        alert(a);                //显示undefined
        alert(b);                //显示undefined
        var a='test';
        var b='test';
    }
    test();
</script>
复制代码
  综上所述,javascript在执行时的步骤是:
 
    1、先读入第一段代码块
 
    2、对代码块进行语法分析,如果出现语法错误,直接执行第5步骤
 
    3、对var变量和function定义的函数进行“预编译处理”(赋值式函数是不会进行预编译处理的)
 
    4、执行代码块,有错则报错
 
    5、如果还有下一段代码块,则读入下一段代码块,重复步骤2
 
    6、结束

JS的预编译和执行顺序 详析的更多相关文章

  1. JS的预编译和执行顺序 详析(及全局与局部变量)

    最近在复习javascript的事件处理时发现了一个问题,于是总结一下:javascript的预编译和执行顺序的问题:   <html> <head> <title> ...

  2. JS 的预编译和执行顺序

    脚本执行js引擎做的工作: 语法分析 预编译 解释执行

  3. JS之预编译和执行顺序(全局和函数)

    预编译的两种情况 全局: 1.全局 直接是script标签中的代码,不包括函数执行 执行前: 1.首先生成一个GO(global object)对象,看不到,但是可以模拟出来用来分析 2.分析变量声明 ...

  4. 关于JavaScript预编译和执行顺序以及函数引用类型的思考

    昨晚在对项目中的一部分做模块化处理的时候,遇到了一个问题,一个重新定义的function对一个通用类中的function进行赋值覆盖的时候,失败了.问题抽象出来是这样的: <script > ...

  5. javascript的预编译和执行顺序

    原文:javascript的预编译和执行顺序 最近在复习javascript的事件处理时发现了一个问题,然后也是我来写javascript的预编译和执行顺序的问题 代码: 代码一<html> ...

  6. javascript运行机制之执行顺序详解(转)

    转自http://www.admin10000.com/document/3385.html JavaScript是一种描述型脚本语言,它不同于java或C#等编译性语言,它不需要进行编译成中间语言, ...

  7. javascript 执行顺序详解

    JavaScript是一种描述 型脚本语言,它不同于java或C#等编译性语言,它不需要进行编译成中间语言,而是由浏览器进行动态地解析与执行.如果你不能理解javaScript 语言的运行机制,或者简 ...

  8. javascript运行机制之执行顺序详解

    1.代码块 指的的是有标签分割的代码段. 例如: <script type="text/javascript"> alert("这是代码块一"); ...

  9. JavaScript 运行机制之执行顺序详解

    JavaScript是一种描述型脚本语言,它不同于 Java 或 C# 等编译性语言,它不需要进行编译成中间语言,而是由浏览器进行动态地解析与执行.如果你不能理解 JavaScript 语言的运行机制 ...

随机推荐

  1. POJ3318【随机化算法挺有意思】

    题目链接:http://poj.org/problem?id=3318 http://meizhe143.blog.163.com/blog/static/3893836200710299512136 ...

  2. Codeforces 482 - Diverse Permutation 构造题

    这是一道蛮基础的构造题. - k         +(k - 1)      -(k - 2) 1 + k ,    1 ,         k ,             2,    ....... ...

  3. 【集训笔记】归纳与递推【HDOJ1297

    例:(2050)折线分割平面 问题描述: 平面上有n条折线,问这些折线最多能将平面分割成多少块? 样例输入 1 2 样例输出 2 7 平面上有n条折线,问这些折线最多能将平面分割成多少块? 解: 折线 ...

  4. 基于visual Studio2013解决C语言竞赛题之0422牛顿迭代法

      题目

  5. 2-SAT 及 一点习题

    今天简单学习了一下2-SAT.现在简单地总结一下.至于定义之类的就不写了,这里就写写做法,以防以后忘记. 构图 每个值a,拆为两个点,一个表示a,一个表示^a(非a).每个点我们可以看成是一个命题(这 ...

  6. Codeforces Round #312 (Div. 2)

    好吧,再一次被水题虐了. A. Lala Land and Apple Trees 敲码小技巧:故意添加两个苹果树(-1000000000, 0)和(1000000000, 0)(前者是位置,后者是价 ...

  7. 12 - 多线程、执行队列、GCD

    一.多线程 进程:一个应用程序配套一个进程,进程会加载应用程序的资源,进程是放代码的,一个进程默认是一个线程(主线程),可以有多个线程 线程:执行代码的是线程,一个线程同时只能读取一段代码 栈里的变量 ...

  8. QScriptEngine

    其实你有好多没有介绍 比如qt文字 我一直很迷惑qt的文字的长宽 qt文字的字间距 等等这些东西还有QProcess QProcess可能是qt调用c#的唯一方法了QScript要比你想象的重要,一个 ...

  9. 基于visual Studio2013解决C语言竞赛题之1009补数

         题目 解决代码及点评 /************************************************************************/ ...

  10. cmake手册详解----转

    参考链接:http://www.cnblogs.com/coderfenghc/tag/cmake/