JS的解析与执行过程—函数预处理

声明:之所以分为全局预处理与函数预处理,只是为了理解方便,其实在实际运行中二者是不分先后的。

函数预处理阶段与全局预处理的差别:

  • 函数每调用一次,就会产生一个LexicalEnviroment对象,在全局预处理中该对象就是window对象,但在函数预处理中该对象是不可见,无法访问的,因为他是JS解析器的东西。
  • 函数是有参数的,在预处理时函数参数也会成为词法环境对象的成员;

然后函数内的声明式函数,var 声明式变量,冲突处理情况与全局的是一样的。

代码如下:

 1 <body>
 2     <script>
 3         function f(a, b) {
 4             alert(a);
 5             alert(b);
 6 
 7             var b = 100;
 8             function a() {
 9                 
10             }
11         }
12         f(1, 2);
13     </script>
14 </body>

预处理的词法环境对象如下:

 1 lexcial env: {
 2     a: 指向函数的引用,
 3     b: 2,
 4 
 5     //函数独有的
 6     arguments: 
 7 }
 8 
 9 假如有函数:
10 function xxx(a, b){
11 
12 }
13 调用时只传了一个参数
14 xxx(a);
15 那么词法环境对象为:
16 lexcial env: {
17     a: a;
18     b: undefimed
19 }

因为后面的var b 和函数 a命名冲突,所以按照原则处理,a由原本的参数被替换为函数引用,b不变,所以执行结果为函数a的字符串表示,2。

然后在执行阶段:

  • 给预处理的成员赋值。
  • 多个函数嵌套,每个函数都有一个LexcialEnviromment对象。
  • 函数里面没有使用var声明的变量会成为最外层的LexcialEnviromment的成员,即全局变量。

猜你喜欢

转载自www.cnblogs.com/jixiaohua/p/10487053.html
今日推荐