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

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

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

 

  代码:

 

复制代码

代码一

<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;

                }

                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、结束

时间: 2024-10-20 11:27:07

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

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

最近在复习javascript的事件处理时发现了一个问题,于是总结一下:javascript的预编译和执行顺序的问题:   <html> <head> <title>事件处理</title> <meta http-equiv="content-type" content="text/html;charset=utf-8"/> <script type='text/javascript'> //页

javascript的预编译和执行顺序

最近在复习javascript的事件处理时发现了一个问题,然后也是我来写javascript的预编译和执行顺序的问题 代码: 代码一<html> <head> <title>事件处理</title> <meta http-equiv="content-type" content="text/html;charset=utf-8"/> <script type='text/javascript'>

JavaScript执行顺序详解

这篇文章主要介绍了JavaScript执行顺序,有需要的朋友可以参考一下 之前从JavaScript引擎的解析机制来探索JavaScript的工作原理,下面我们以更形象的示例来说明JavaScript代码在页面中的执行顺序.如果说,JavaScript引擎的工作机制比较深奥是因为它属于底层行为,那么JavaScript代码执行顺序就比较形象了,因为我们可以直观感觉到这种执行顺序,当然JavaScript代码的执行顺序是比较复杂的,所以在深入JavaScript语言之前也有必要对其进行剖析.1.1

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

JavaScript是怎么来进行解析的吗?它的执行顺序又是如何的呢?在了解这些之前,我们先来认识几个重要的术语: 1.代码块 JavaScript中的代码块是指由<script>标签分割的代码段.例如: <script type="text/javascript"> alert("这是代码块一"); </script> <script type="text/javascript"> alert(&q

js 变量预编译

js是按照顺序执行的: 但是在js中会对var和function进行预编译: alert(show); function show(){ var a; } 比如以上代码,alert就会输出function. 但是对于var的预编译,刚刚是自己理解错了, 如下代码,a输出都是undefined. b会直接报错,b is not defined. alert(a); alert(b); var a; 汇总下要点: 1.js在页面加载过程中顺序执行.但是分块预编译.执行. 2.JS 在执行前会进行类似

js的预编译

js执行的三步:语法检查,预编译,解释执行. js预编译前:window对象==全局 1.任何位置上的变量未声明直接赋值是全局变量,发到window里 2.在函数外声明的变量也是全局,放到window里. js预编译时:对函数来说 1.生成函数的AO对象(作用域) 2.把函数的形参和变量声明放到AO对象中,作为属性 3.形参和实参相对应(实参的值传给形参) 4.把函数声明的函数名放到AO对象里,作为属性 js预编译结束后,进行解释执行,执行时,变量和函数的声明不执行 原文地址:https://w

wex5 实战 wex5与js的组件关系与执行顺序(父子与先后)

初学wex5,先理理让人容易混淆的三个概念: 一 基本概念: 1 wex5组件,顾名思义,在编辑窗口右侧的组件集合里的,都是wex5基于开源自创的组件,并封装了一套自已的方法.目的是为了方便.相关方法在api有提示,操作中也有提示. 2 js对像 JavaScript 中的所有事物都是对象:字符串.数值.数组.函数... 此外,JavaScript 允许自定义对象. 二 对像获取与取值方法 1 wex5 this.comp() 效能较低,但操作方便 取值方法:this.comp().val()

unity脚本执行顺序详解

unity脚本自带函数执行顺序如下:将下面脚本挂在任意物体运行即可得到 Awake ->OnEable-> Start ->-> FixedUpdate-> Update  -> LateUpdate ->OnGUI ->Reset -> OnDisable ->OnDestroy using UnityEngine; using System.Collections; public class timetest : MonoBehaviour

js编译和执行顺序

JS是一段一段执行的(以<script>标签来分割),执行每一段之前,都有一个“预编译”,预编译干的活是:声明所有var变量(初始为undefined),解析定义式函数语句. 还有个关于 "window作用域下,a = 1和var a = 1" 的区别的也很经典: a = 1相当于window.a = 1,是动态地为window添加一个成员: var a = 1是在当前作用域(也就是window)下声明一个a,这个声明是在整个作用域内都有效的. 换句话说,其实区别就在于va