zoukankan      html  css  js  c++  java
  • JS预解析

    以下为个人对JS预解析的理解,有不正确的地方,希望您能提出,欢迎访问,不喜可喷。

    JS解析过程:先预解析,然后逐行的解读代码。

    那么我们带着几个问题去看下面的代码,我先给出答案,在下文给出解释。

    一、预先解析哪些东西?

      --预先解析 var 和  function 

    二、预解析的顺序?

      --首先是找到<script></script>标签,按照<script>块依次解析。

      --按执行环境解析

      --对 var 和 function 进行解析

    1、先来一段小代码,简单说一下原理

    <script>
        console.log(a);   //undefined
        var a = 10;
        function fn(argument) {
            console.log(a);   //  undefined
            var a = 100;
        }
        fn();
    </script>

    这段代码中,有两个作用域:

      一个是全局作用域:作用域下有 a ,fn 。

      一个是fn的内部作用域: 作用域下有 argument(参数,我们将参数和函数内的局部变量同等看待),局部变量 a 。

    这两个作用域就是预解析的执行环境,JS会先在全局环境中进行预解析,查找 var a 预先解析到内存,而没有给变量赋值,所以输出结果为undefined; 然后把function fn解析到内存,所以调用fn() 照常弹出结果;  在局部作用域中预解析也是一样的,先将var a预先解析到内存,并未赋值,所以输出结果为undefined;

    2、接下来我们看一下变量和函数重名的时候会是什么情况?

    <script>
        console.log(fn);   // fn()
        var fn = 10;
        function fn() {
            var a = 100;
        }
        console.log(fn);    //  10
        fn();       //  报错:fn is not a function
    </script>

    输出的结果:

    为什么会是这样的结果?

      是因为function预解析时会被置顶,就像是优先级高的说法;同名function预解析时会覆盖同名的var;

      在解读JS时var fn=10;function fn会跳过,说以fn为10,所以执行fn()时报错 “fn is not a function” ;

    3、我们现在举个例子说明一下按照<script>块依次解析的问题:

    <script>
        alert(msg);  //报错 msg is not defined
        //test();   //报错 test is not defined
    </script>
    <script>
        var msg ="123456";
         function test(){
            alert("1234567");
         }
    </script>

    这里有两个script块,他们是按照顺序进行预解析的,我们在第二个script块中定义的var msg,而在第一个script块中alert(msg);

    显然在第一个script快中并没有预解析到一个叫msg的变量或者函数,而js又不会跨到第二个script块去解析,所以就报错msg未定义;

    将两个代码块调换就是另一种结果:

    <script>
        var msg ="123456";
         function test(){
            return "1234567"
         }
    </script>
    <script>
        console.log(msg);  // "123456"
        console.log(test());   //"1234567"
    </script>

    结果:

    当第一个script块预解析完,会解析到var msg 和function test,所以当第二个script块中执行console.log(msg)和console.log(test())时;上面的js程序已经执行完毕了,自然会输出 123456 和1234567;

    4、假如一个变量我们不是用var声明的呢?

    <script>
        console.log(msg)
        msg ="123456";
    </script>

    结果:

    这也是为什么我们不推荐不去使用var声明变量的原因,我们说过Js预解析是对 var 和 function 进行解析。所以这里会报错。

    不知道你理解了JS预解析没有,那我们来测试一下,哈哈

    <script>
        console.log(a);
        var a = 1;
        console.log(a);
        function a() {
            console.log(2)
        }
        console.log(a);
        var a = 3;
        console.log(a);
        function a() {
            console.log(4)
        }
        console.log(a);
        a();
    </script>

    这是不是你想要的结果呢? 

  • 相关阅读:
    基于SOA分布式架构的dubbo框架基础学习篇
    项目管理 绩效考核
    性能测试晋级教程
    从页面走向单元实现真正的业务驱动
    微软的开源Sonar工具测试网站的性能和安全性
    2.动手实操Apache ZooKeeper
    1. Apache ZooKeeper快速课程入门
    开发人员的福音:微软、谷歌、Mozilla将他们所有的Web API文档放在同一个地方
    Happy Java:定义泛型参数的方法
    比较两个文件不同以及生成SQL插入语句
  • 原文地址:https://www.cnblogs.com/hjbky/p/8446597.html
Copyright © 2011-2022 走看看