zoukankan      html  css  js  c++  java
  • 转:JavaScript预编译与执行顺序的关系

    首先关于函数的:

    在Javascript中,function才是Javascript的第一型。当我们写下一段函数时,其实不过是建立了一个function类型的实体。

    就像我们可以写成这样的形式一样:

    function Hello() {
                alert("Hello");
            }
            Hello();
            var Hello = function () {
                alert("Hello");
            }
            Hello();

    其实都是一样的。

    但是当我们对其中的函数进行修改时,会发现很奇怪的问题。

        <script type="text/javascript">
            function Hello() {
                alert("Hello");
            }
            Hello();
            function Hello() {
                alert("Hello World");
            }
            Hello();
        </script>
    

    我们会看到这样的结果:连续输出了两次Hello World。而非我们想象中的Hello和Hello World。

    这是因为Javascript并非完全的按顺序解释执行,而是在解释之前会对Javascript进行一次“预编译”,在预编译的过程中,会把定义式的函数优先执行,也会把所有var变量创建,默认值为undefined,以提高程序的执行效率。也就是说上面的一段代码其实被JS引擎预编译为这样的形式:

        <script type="text/javascript">
            var Hello = function() {
                alert("Hello");
            }
            Hello = function() {
                alert("Hello World");
            }
            Hello();
            Hello();
        </script>
    

    我们可以通过上面的代码很清晰地看到,其实函数也是数据,也是变量,我们也可以对“函数“进行赋值(重赋值)。当然,我们为了防止这样的情况,也可以这样:

        <script type="text/javascript">
            function Hello() {
                alert("Hello");
            }
            Hello();
        </script>
        <script type="text/javascript">
            function Hello() {
                alert("Hello World");
            }
            Hello();
        </script>
    

    这样,程序被分成了两段,JS引擎也就不会把他们放到一起

     JS在执行每一段JS代码..

    1. <script>
    2.      alert(typeof eve); //结果:undefined
    3. </script>
    4. <script>
    5.      function eve() {
    6.           alert('I am Laruence');
    7.      }
    8. </script>

    JS的预编译是以段为处理单元的

    了。http://www.cnblogs.com/kym/archive/2010/01/06/1640030.html

    对于函数的定义,是一个要注意的地方:

    1. <script>
    2.      alert(typeof eve); //结果:function
    3.      alert(typeof walle); //结果:undefined脚本报错
    4.      function eve() { //函数定义式
    5.           alert('I am Laruence');
    6.      };
    7.      var walle = function() { //函数表达式
    8.      }
    9.      alert(typeof walle); //结果:function
    10. </script>

    这就是函数定义式和函数表达式的不同, 对于函数定义式, 会将函数定义提前. 而函数表达式, 会在执行过程中才计算.

    当JavaScript引擎解析脚本时,它会在预编译期对所有声明的变量和函数进行处理。 
    做如下处理: 
    1. 在执行前会进行类似“预编译”的操作:首先会创建一个当前执行环境下的活动对象,并将那些用var申明的变量设置为活动对象的属性,但是此时这些变量的赋值都是undefined,并将那些以function定义的函数也添加为活动对象的属性,而且它们的值正是函数的定义。 
    2. 在解释执行阶段,遇到变量需要解析时,会首先从当前执行环境的活动对象中查找,如果没有找到而且该执行环境的拥有者有prototype属性时则会从prototype链中查找,否则将会按照作用域链查找。遇到var a = ...这样的语句时会给相应的变量进行赋值(注意:变量的赋值是在解释执行阶段完成的,如果在这之前使用变量,它的值会是undefined) 
    所以,就会出现当JavaScript解释器执行下面脚本时不会报错: 

     
    1. alert(a);    // 返回值undefined  
    2. var a =1;  
    3. alert(a);    // 返回值1  


    由于变量声明是在预编译期被处理的,所以在执行期间对于所有代码来说,都是可见的。但是,你也会看到,执行上面代码,提示的值是undefined,而不是1。这是因为,变量初始化过程发生在执行期,而不是预编译期。在执行期,JavaScript解释器是按着代码先后顺序进行解析的,如果在前面代码行中没有为变量赋值,则JavaScript解释器会使用默认值undefined。由于在第二行中为变量a赋值了,所以在第三行代码中会提示变量a的值为1,而不是undefined。

  • 相关阅读:
    破解Mac版MyEclipse-2017-ci3
    JAVA8 十大新特性详解
    Java 1.8 时间日期库的20个使用示例
    20180206 反射中模块化开发的上课思路
    反射在数据库读写中的应用
    浅谈多线程并发
    Mac OS Git 安装
    MAC node + git + bower 简单安装
    Mac OS 下 eclipse中文乱码解决方法(eclipse for mac 中文乱码)
    【精华】MacOS 10.13.2 环境下安装eclipse
  • 原文地址:https://www.cnblogs.com/youxin/p/2950812.html
Copyright © 2011-2022 走看看