作用域 -JS解析器如何解析JS代码2

来源:互联网 发布:软件测试培训总结 编辑:程序博客网 时间:2024/05/18 06:39

只要在<script></script>标签中就是域,有域就要进行域解析(如何进行域解析参考上篇文章作用域 - JS解析器如何解析js代码?)。

如果一个页面中有两块标签。第二个域可以读取上一个域中的仓库。
所以一般我们引用库的时候会先把库写在上面,然后下面再写我们自己的js代码。

script:全局变量、全局函数;
函数、json对象也是域,只要是域就要进行域解析;

例1、

函数体内有var.

var a = 1;function fn1(){    alert(a);//undefined    var a =2;}fn1();alert(a);//1

解析:

第一步、预解析

1、首先读到第一行发现‘var’,于是存储‘a =undefined’;
2、读到第二行发现‘function’,于是存储‘fn1 = function fn1(){alert(a);var a =2;}’整个函数块都存储下来;
预解析结束。

第二步、逐行解析代码

1、第一行看到a,于是到仓库去找a,然后看到等号,就是表达式,会到仓库去更改值,由‘a=未定义’更改成‘a=1’;
2、第二行看到function函数,就是声明,不能对值进行修改,仓库中a 的值还是1不变。
3、继续读代码看到fn1();函数调用,就是让函数里面的代码开始执行。我们知道函数也是一个域,只要是域就会发生域解析,于是函数里面的代码要先进行预解析,再逐行解读代码。如下:①②
①预解析:第一行alert(a);没有要找的关键字;第二行var a =2;看到var关键字,于是把a=未定义存储在仓库中。
②逐行解读代码:第一行看到a,于是到局部仓库去找a,弹出a=undefined;
第二行看到a,继续到仓库去找a.然后又看到等号,就是表达式,于是更改仓库中a的值为a=2;
注意:在函数内进行的预解析,跟函数外面仓库中的值没有关系。
4、继续读代码alert(a);,看到a,然后到仓库去找a的值,a=1,弹出1。

例2、

当函数体内没有var。

var a = 1;function fn1(){    alert(a);//1    a =2;}fn1();alert(a);//2

解析:

第一步、预解析

1、首先读到第一行发现‘var’,于是存储‘a =undefined’;
2、读到第二行发现‘function’,于是存储‘fn1 = function fn1(){alert(a); a =2;}’整个函数块都存储下来;
预解析结束。

第二步、逐行解析代码

1、第一行看到a,于是到仓库去找a,然后看到等号,就是表达式,会到仓库去更改值,由‘a=未定义’更改成‘a=1’;
2、第二行看到function函数,就是声明,不能对值进行修改,仓库中a 的值还是1不变。
3、继续读代码看到fn1();函数调用,就是让函数里面的代码开始执行。我们知道函数也是一个域,只要是域就会发生域解析,于是函数里面的代码要先进行预解析,再逐行解读代码。如下:①②
①预解析:第一行alert(a);没有要找的关键字;第二行a =2;也没有要找的关键字。于是预解析结束。局部仓库没有存储任何东西。
②逐行解读代码:第一行看到a,于是到局部仓库去找a,局部仓库没有找到a,于是从这层的作用域跳到外层作用域去找a(子集作用域到父级作用域去找,我们叫做作用域链),弹出a=1;第二行看到a,于是在局部作用域仓库找a,没有找到,于是到函数外面作用域继续找,找到a,然后又看到等号,于是把函数外面a的值更改为2,即仓库中存储的a = 2;
函数调用结束;
4、继续读代码‘alert(a);’,看到a,于是在仓库中找a ,找到a = 2,于是弹出2;

注意:子集作用域到父级作用域去找,我们叫做作用域链

例3、

当函数中有参数时

var a = 1;function fn1(a){//添加参数    alert(a);//undefined    a =2;}fn1();alert(a);

解析:

第一步、预解析

1、首先读到第一行发现‘var’,于是存储‘a =undefined’;
2、读到第二行发现‘function’,于是存储‘fn1 = function fn1(a){alert(a); a =2;}’整个函数块都存储下来;
预解析结束。

第二步、逐行解析代码

1、第一行看到a,于是到仓库去找a,然后看到等号,就是表达式,会到仓库去更改值,由‘a=未定义’更改成‘a=1’;
2、第二行看到function函数,就是声明,不能对值进行修改,仓库中a 的值还是1不变。
3、继续读代码看到fn1();函数调用,就是让函数里面的代码开始执行。我们知道函数也是一个域,只要是域就会发生域解析,于是函数里面的代码要先进行预解析,再逐行解读代码。如下:①②
①预解析:函数第一行function fn1(a){看到参数a,是要找的关键字;参数本质上就是局部变量,function fn1(var a),但是在函数调用时并没有传参进来,就相当于放着一个空值在这,即函数体的仓库中存放着a = 未定义;
由此局部预解析结束;
②逐行解读代码:第一行看到alert(a);,于是到局部仓库去找a,局部仓库中a的值是未定义,所以弹出来undefined;继续读代码a =2;,看到a后到局部仓库中去寻找a,然后看到等号,于是把局部仓库中a的值更改为a = 2;
函数调用解析结束;
4、继续解读代码,看到alert(a);,于是到仓库中寻找a,弹出1(因为是到外面的大仓库中寻找,不是局部仓库)。

原创粉丝点击