首页 > 代码库 > 1、JS预解析原理(一)

1、JS预解析原理(一)

一、作用域概念、预解析规则、表达式

1、作用域概念

什么是作用域:简单说就是作用的范围,指的是函数在哪些范围内可以用,而在其他部分就不可以使用,如果需要使用就需要重新定义。

作用域的作用是什么:用来执行读或者写的操作。

2、预解析规则

script:自上而下进行解析,

函数:由里到外进行解析。

但是浏览器在执行JS代码的时候会分成两部分操作:预解析以及逐行执行代码

预解析:浏览器在开始工作的时候会先解读JS代码的关键字:比如:var function 参数等,并把解析到的内容存入一个类似仓库的地方,这个过程一般称为JS预解析。

并且,在这个阶段所有的变量,在正式运行代码之前,都会提前赋值为未定义。

<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8"/>
        <title></title>
        <script>
            alert(a);
            var a = 1;
        </script>
    </head>
</html>

代码执行结果

技术分享

函数在正式运行代码之前则是整个函数块。

<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8"/>
        <title></title>
        <script>
            alert(a);
            function a () {
                alert(2);
            }
        </script>
    </head>
</html>

 

代码执行结果

技术分享

在这个过程中如果函数和变量重名的话只会保留函数。

<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8"/>
        <title></title>
        <script>
            alert(a);
            var a = 1;
            function a () {
                alert(2);
            }
        </script>
    </head>
</html>

代码执行结果:

技术分享

逐行解读代码:在这个阶段浏览器会一行一行的进行解读,并找到关键字然后调用预解析阶段储存在“仓库”的信息。

<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8"/>
        <title></title>
        <script>
            alert(a);
            var a = 1;
            alert(a);
            function a () {
                alert(2);
            }
            alert(a);
            var a = 3;
            alert(a);
            function a () {
                alert(4);
            }
            alert(a);
        </script>
    </head>
</html>

  首先在这个阶段已经完成了代码的预解析,通过代码的预解析我们知道预解析的结果为 a = function a () { alert(4)},

那么上边的代码第一次弹出的一定是a = function a () { alert(4)}请看下图

技术分享

当执行到第二行时(也就是 var a = 1;)这个时候由于我们对a进行了赋值,所以第三行alert的展示结果应该是1;

技术分享

当执行到第四行的时候(function a () { alert(2)};)由于它又变成了函数,但是由于函数不是表达式它不会改变值,所以执行完第五行之后会弹出1;

技术分享

当代码执行到第六行(var a = 3;)的时候,由于我们给变量进行了赋值,此时a=1变成了a=3;所以第七行弹出的结果为3;

技术分享

当代码执行到第八行的时候(function a(){  alert();}由于函数不改变值的原则,所以第九行弹出的结果依旧为3;

技术分享

最后当代码解读完毕之后这个时候“仓库”里边储存的信息就是这样的  a = 3;怎么确认这个结果就是数字呢,我们可以使用typeof进行验证

<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8"/>
        <title></title>
        <script>
            alert(a);
            var a = 1;
            alert(a);
            function a () {
                alert(2);
            }
            alert(a);
            var a = 3;
            alert(a);
            function a () {
                alert(4);
            }
            alert(a);
            alert(typeof a);
        </script>
    </head>
</html>

执行结果为

技术分享

3、表达式

在将上边的问题的时候我们遇到一个现象:就是函数不会改变值,但是表达式却可以。

首先先来总结一下表达式有哪些?

表达式:= + - * / % ++ -- ! 参数……

作用:表达式可以修改预解析的值!

1、JS预解析原理(一)