干货!Js预编译详解!!!

1,082 阅读4分钟

干货!干货!干货!彻底理解预编译!!!

本文会详细解释Js预编译

Javascript是解释性语言,什么是解释型语言?

答:逐行解析 逐行执行。

预编译是啥?

答:在js被解析之前,js解析引擎会把整个文件进行预处理 这个预处理的过程就被称为预编译。

预编译是啥时候发生的?

答:在函数执行的前一刻。

 console.log(test);   //打印什么?
 var test = 100;
 function test(){    //打印什么?
     console.log(test);  //打印什么
 }
 test();

自己动手去试一试吧

全局对象 (Global Obejct) 我们简称GO

浏览器环境中 js内部引擎会整个script标签中的内容 产生window对象 ,window是全局对象,是完全等于GO的,GO === window

全局变量

在script中声明的变量为全局变量,还有未经声明就直接赋值的,也是属于window对象的,而window === GO,所以也是属于GO的

 var test = 100;
 test1 = 100;  //未经声明的变量,也属于window
 console.log(window.test);
 console.log(window.test1);  //可以正常输出

自己动手去试一试吧

全局函数

在script中声明的函数为全局函数

 function test1() {
      console.log('i like fish');
 }
 test1()

激活对象 (Activation Obejct) 简称AO

函数调用时候产生AO 用来保存当前函数内部的执行环境

函数调用结束后销毁 如果函数重新调用 会创建一个新的AO

提示:这里略微看一下就行

局部变量

啥事局部变量?

答:在函数内部声明的变量叫做局部变量 作为AO对象的属性存在

局部函数

在函数内部声明的函数叫做局部函数 局部函数作为AO对象的方法存在

 function test() {
     function test1() {
         console.log('i like fish')
     }
     test1();
 }
 test();

自己动手试试吧

经过我们上面知识的铺垫,我们进入正题

全局预编译

  1. 第一步:创建全局对象GO (window对象);
  2. 第二步:变量声明提前,将所有变量的声明放在最前面,赋值为undefined,存在变量名相同, 只声明一个。
  3. 第三步:函数声明提前,将函数声明放在最前面。函数名如果跟变量名相同,函数名会覆盖变量名 值是函数体
  4. 第四步:全局预编译结束,结束后代码从上到下
 console.log(test);        //输出 function test() {};
 var test = 100;     
 console.log(test);        //输出 100;
 function test() {   
    console.log(111);      
 }
 console.log(test);        //输出 100;
 
 全局预编译环节分析:
     1 创建GO对象
     2 变量声明提前 值为undefined
                     01. 找到了变量声明:var test = 100;
                     02. test: undefined
     3 函数声明提前,同名覆盖 值为函数体
                     01. 找到了函数声明 function() {...}
                     02. test: function(){}
     4 预编译结束 从上到下执行代码
     
 题目分析:
           预编译最后一个环节test = function() {...}
           所以打印function(){}
           代码执行到var = 100;的时候 test里面的值从function(){}
           更换为100,所以第二个console.log打印的还是100 到了函数
           体的时候 会略过,因为被提升了,直接输出下面的100

自己动手试试吧。

函数预编译

  1. 第一步:创建AO对象
  2. 第二步:找出形参和变量声明,值赋予undefined
  3. 第三步:实参,形参值相统一
  4. 第四步:在函数体里面找到函数声明,值赋予函数体
   function test1(a) {
     console.log(b);       //1  输出 function b(){}
     var b = 0;
     console.log(b);      //2  输出 0
     console.log(a);      //3  输出 function a(){}
     function a() {
 ​
     }
     function b() {
 ​
     }
 }
 test1(1);
 
 分析函数预编译
     1 创建AO对象
     2 找出形参,变量声明 值为undefined
                         01. 找到了形参a 
                             a: undefined
                             找到了变量声明 var b = 0;
                             b: undefined
                         
     3 实参,形参 值统一
                         02. a: 1
                             b: undefined
     4 找出函数声明 值为函数体
                         03. a: function a() {}
                             b: function b() {}
 ​
 题目分析: 
             预编译结束之后,会从上到下执行代码 第一个打印function b(){},
             没问题 当执行到var b = 0;的时候,会把b里面的函数更改为0, 
             下面打印0,最后输出函数a没问题,因为预编译最后环节 a里面保存
             的是function a(){}

自己动手试试吧。

小提示:在预编译环节 不管你有没有if判断之类的条件语句,预编译都会给你打破,把里面的值拿出来

到这里也就和大家说再见啦,下期再见。