从一个实例中解释分析javascript 中的预编译

引言

在咱们写了不少关于业务逻辑的代码后、过程当中会遇到不少关于变量定义、变量提高、做用域的问题,理解完预编译就清晰不少javascript

关于javascript运行的三个阶段

1.语法分析

引擎检查你的代码有没有什么低级的语法错误java

2.预编译

预编译简单理解就是在内存中开辟一些空间,存放一些变量与函数面试

3.解释执行

解释执行顾名思义即是执行代码了bash

关于预编译发生的时机

发生在script内代码块执行前、也能够说预编译发生在函数执行的前一刻函数

从这个例子解释疑惑

对于这样一段代码,常常在不少面试中会看到测试

let a = 0
function test(a,b){
    console.log(a)
    console.log(b)
    a = 1
    console.log(a)
    console.log(c)
    function c(){}
    function a(){}
    console.log(a)
}

test(1)
复制代码

请问这段代码的输出是? 对于这样的函数预编译,咱们能够记住预编译的4个步骤ui

  • 建立AO对象
  • 找形参和变量声明,将形参和变量名做为AO对象的属性名,值为undefined
  • 将实参和形参统一
  • 函数的提高,在函数块内找函数声明,并修改对应属性名的值,在下文解释执行的阶段改function将不会改变对象中属性名的值

听起来有点生涩难懂,可是咱们一行一行跟着这四个步骤一块儿作的时候就明朗了spa

开始解题code

  • 建立AO对象,也称活动对象,全程能够理解为active object,就是创建了一个空对象
AO{
    
}
复制代码
  • 找形参和变量声明,在test这个函数中形参有a,b,咱们把它写到这个对象中,并把他们的值设置为undefined
AO{
    a : undefined,
    b : undefined
}
复制代码
  • 将实参和形参统一,第三步咱们须要去找到函数的参数,而且去改写已经存在的属性名的值,这个test函数的参数只传了一个a:1,因此咱们改写一下这个AO对象
AO{
    a : 1,
    b : undefined
}
复制代码
  • 第四步也是我我的认为最难理解的一个步骤,找到改函数体内的函数声明
知足 function a(){}这样的叫函数声明 而相似于let a = function(){} 这样的并非函数声明
复制代码

咱们找到了a、c函数声明,咱们须要去改写AO对象中对应的属性名,因为c这个属性名并不存在,咱们要建立并用函数赋值,所以咱们获得了这样一个对象对象

AO{
    a : function(){},
    b : undefined,
    c : function(){}
}
复制代码

而且在函数的解释执行阶段并不会对对应AO对象的属性名进行值的改写

至此,预编译阶段结束,进行到函数的解释执行阶段

let a = 0

/**
 * 测试函数
 * @param {*} a 
 * @param {*} b 
 * 
 * 
 * 
 * 咱们在预编译结束的时候获得这样一个对象
 * {
 *  a:function(){},
 *  b:undefined,
 *  c:function(){}
 * }
 */
function test(a,b){
    console.log(a)
    console.log(b)
    a = 1
    console.log(a)
    console.log(c)
    function c(){}
    function a(){}
    console.log(a)
}

test(1)
复制代码

下面咱们会逐字逐句解释打印的值

  • 从第一行开始 第一个console.log(a) 得到的值应该是function(){}
  • console.log(b) 打印的应该是AO对象中b的值 为undefined
  • a = 1 这一行会改写AO对象的a的值
{
    a : 1,
    b : undefined,
    c : function(){}
}
复制代码
  • 因此 a = 1 后面一行的console.log(a) 应该打印出1
  • console.log(c) 打印AO对象中的c的值 为 function(){}
  • 我在第四个步骤中谈到了在解释执行阶段的函数声明并不会去修改AO对象中的属性名的值了 因此function a(){} function c(){}不会修改AO对象了
  • 最后一个console.log(a) 打印出的值应该是 1

至此、这个实例解释完毕

若是从全局出发,则是建立一个GO对象,顾名思义Global Object,其四个步骤和函数内的预编译四个步骤同样

相关文章
相关标签/搜索