原文: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. 响应式Web图形篇 —— icon fonts 的探析及应用

    前言 像素完美(Pixel Perfection).分辨率无关(Resolution Independent)和多平台体验一致性是设计师们的追求. 可访问性(Accessability).加载性能和重 ...

  2. LNK 2005 error 函数定义也是定义!!

    url=Ccne-rWwUO9tJp5YAPcycUw09__2whgZLpLw2aWVuYuE-fhu46kaVNX4BldWlsxig1tDML47aO_ctD3PcUlGjK"> ...

  3. C语言,单链表操作(增删改查)(version 0.1)

    这天要面试,提前把链表操作重新写了一遍.备份一下,以备不时之需. 希望有人能看到这篇代码,并指正. // File Name : list.h #include "stdafx.h" ...

  4. myeclipse8.5如何注册,转自他出

    Step: 1.建立一个任意名称的Java Project 2.在该工程中建立一个名文MyEclipseGen的Java文件(MyEclipseGen.java) 3.运行下面的代码,会在控制台出现& ...

  5. BZOJ 2718: [Violet 4]毕业旅行( 最长反链 )

    一不小心速度就成了#1.... 这道题显然是求最长反链, 最长反链=最小链覆盖.最小链覆盖就是先做一次floyd传递闭包, 再求最小路径覆盖. 最小路径覆盖=N - 二分图最大匹配. 所以把所有点拆成 ...

  6. ZOJ 3490 String Successor 字符串处理

    一道模拟题,来模拟进位 暴力的从右往左扫描,按规则求后继就好了.除了Sample已给出的,还有一些需要注意的地方: 9的后继是10,而不是00: (z)的后继是(aa),而不是a(a): 输入虽然最长 ...

  7. php unset 数组陷阱

    我们删除一个array, unset($arr); 想删除某个元素 unsert($arr[i]) 一个陷阱是: unset() 函数允许删除数组中的某个键.但要注意数组将不会重建索引.如果需要删除后 ...

  8. 黑马程序员 ---> 正则表达式

    --------------- ASP.Net+Android+IO开发S..Net培训.期待与您交流! --------------- 正则表达式 一.概述: 1.概念:符合一定规则的表达式. 2. ...

  9. NYOJ-开灯问题

    开灯问题 时间限制:3000 ms  |  内存限制:65535 KB 难度: 描写叙述 有n盏灯,编号为1~n.第1个人把全部灯打开,第2个人按下全部编号为2 的倍数的开关(这些灯将被关掉),第3  ...

  10. stm32内部的CAN总线

    功能概述: bxCAN是基本扩展CAN(Basic Extended CAN)的缩写,它支持CAN协议2.0A和2.0B:它的设计目标是以最小的CPU负载来高效处理大量的报文.它也支持报文发送的优先级 ...