JS:预编译

我们知道在表示符提升问题上是声明的变量先提升,函数整体后提升;

我们把变量分为局部变量和全局变量,其区别是作用域不同,局部变量在函数内部的作用域内,但有时我们也会遇到函数内部的变量是全局变量,因为他未在内部被声明;

在JS中,系统首先会检测我们的语法错误,再进行预编译,最后逐条执行;

我们所学的表示提升就是在预编译这个环节进行的;

 

函数预编译的流程:

1、在函数被调用之后,代码执行之前

2、函数每次调用都会生成一个对象:执行期上下文对象

3、给AO对象添加成员:函数内部的局部变量和形参变量名,作为AO对象的属性名

4、把传入的实参赋值给AO对象的属性

5、局部函数声明、赋值,把局部函数的名字让AO对象也有一个一样的成员名,把函数体赋值给这个属性

6、运行代码,预编译过的不再运行

 

全局预编译的流程:

1、生成一个对象Global Object  (GO)

2、把所有的全局变量 设置为GO的属性名

3、把所有函数名 作为GO的成员名,把函数体赋值给这个成员

4、执行代码

 

对比以下三个代码:

        console.log(a);
        a= 1;

打印结果:报错 a未定义

        console.log(a) ;
       var a = 1 ;  //提升了变量,值没有提升;

打印结果:undefined

        console.log(window.a);
        a = 1; //相当于把window.a 赋值为1;

打印结果:undefined

在全局中,a = 1;var  a = 1;区别在于没有var 就没有提升变量;

 

在js环境中运行代码:

       GO对象的成员全部浅拷贝给环境对象window
*node.js 环境中没有这一步
       拓展知识:
  关于访问成员 console.log(a) 访问的是GO对象的成员(作用域链中没有就报错)
       console.log(window.a) 不报错 原型链没有返回undefined
 
 
posted on 2022-06-23 16:42  香香鲲  阅读(39)  评论(0编辑  收藏  举报