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>

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

原文地址:https://www.cnblogs.com/hjbky/p/8446597.html