web前端Javascript开发学习之JavaScript中的预编译如何进行
小职 2021-05-06 来源 :Java面试官Luck 阅读 614 评论 0

摘要:本文主要介绍了web前端Javascript开发学习之JavaScript中的预编译如何进行,通过具体的内容向大家展现,希望对大家前端Javascript开发的学习有所帮助。

本文主要介绍了web前端Javascript开发学习之JavaScript中的预编译如何进行,通过具体的内容向大家展现,希望对大家前端Javascript开发的学习有所帮助。

web前端Javascript开发学习之JavaScript中的预编译如何进行

前言

预编译,顾名思义就是是做些代码文本的替换工作。是整个编译过程的最先做的工作。JavaScript 的圣经 —— MDN 明确地说过, JavaScript 是一个解释型语言,而并非编译型语言,所以预编译对于JS来说是子虚乌有的。但是人们喜欢称之为预编译其实也无伤大雅,关键在于为什么人们会认为JS存在预编译,是JS的哪种行为让人们觉得它产生了预编译呢?让我们来简单聊一聊。

 

引入

在代码执行前,编译器会进行如下操作:

 

一 parse阶段

分词。就是将代码分成原子符号(token)

 

将token解析翻译成AST(语法生成树)。

 

二 analyze阶段

遇到声明语句,将会把声明传到作用域(scope)中创建绑定,分配内存并将变量默认设为undefined或函数体。

 

然后就可以执行代码啦,执行中途每次遇到赋值或者取值,都会从作用域中查找绑定。这样看,是不是有点“预编译”内味了?但是实际上还是称它为预处理更加贴切一点。接下来,让我们来了解一波看起来最像预编译的操作--第三步的干货。

 

“预编译”

我的老师在和我讲相关知识点前和我说过这么一个笑话:

 

面试时我因为这么一个问题挂了

 

var a = 100

function foo(){

    console.log(a)

}

foo()

问:为什么输出a的值是100?

 

答:因为100赋值给了a。

 

老师说完我头昏脑涨,完全不明白笑点在哪,后来才知道这是在考察“预编译”这方面的知识。

 

总的来说,“预编译”可以分为

 

创建GO对象(global object) 发生在页面加载完成时

 

创建AO对象(activation object) 发生在函数执行前一刻

 

具体步骤如下:

 

全局预编译

 

1. 创建GO对象

 

2. 找变量声明,将变量声明作为GO对象的属性名,并赋值undefined

 

3. 找全局里的函数声明,将函数名作为GO对象的属性名,值赋予函数体

 

局部预编译

 

1. 创建一个AO对象

 

2. 找形参和变量声明,将形参和变量声明作为AO对象的属性名,值为undefined

 

3. 将实参和形参统一

 

4. 在函数体里找函数声明,将函数名作为AO对象的属性名,值赋予函数体

 

所以那个笑话里的面试问题我们应该这么回答:

 

首先,编译器创建一个GO对象

 

找到变量声明 var a

 

和函数声明 function foo(){}

 

将上面两个变量声明作为GO的属性名赋初值

 

GO{

 

a:undefined

 

foo:function(){}

 

}

 

然后运行第一行代码 a=100

 

在GO中将100赋值给a

 

再执行第五行代码运行foo函数

 

创建一个AO对象

 

在函数体内找变量声明和形参,(无)

 

再在函数体内找函数声明(无)

 

所以

 

AO{

 

}

 

完成后运行第三行代码,输出a

 

先在AO对象中寻找a的值,发现不存在,向外部作用域扩展,在GO对象中寻找a,发现a的值为100

 

输出100

 

当然,笑话里的题过于简单,但是能让我们清晰的了解到这个“预编译”的进行

 

下面,我们来看一道面试题简化版,练练手:

 

global = 100

    function fn() {

      console.log(global);  

      global = 200

      console.log(global);  

      var global = 300

    }

    fn()

它的逻辑和输出结果是多少呢?通过一步步的分析我们可以知道具体的分析应该是这样的:

 

GO: {

      global: undefined => 100,

      fn: function() {}

    }

    global = 100 // 没有声明的变量默认为全局变量,也会放到GO中

    function fn() {

      console.log(global); // 输出undefined

      global = 200

      console.log(global); // 输出200

      var global = 300

    }

    AO: {

      global: undefined => 200 => 300

    }

    fn() 


我是小职,记得找我

✅ 解锁高薪工作

✅ 免费获取基础课程·答疑解惑·职业测评

web前端Javascript开发学习之JavaScript中的预编译如何进行

本文由 @小职 发布于职坐标。未经许可,禁止转载。
喜欢 | 0 不喜欢 | 0
看完这篇文章有何感觉?已经有0人表态,0%的人喜欢 快给朋友分享吧~
评论(0)
后参与评论

您输入的评论内容中包含违禁敏感词

我知道了

助您圆梦职场 匹配合适岗位
验证码手机号,获得海同独家IT培训资料
选择就业方向:
人工智能物联网
大数据开发/分析
人工智能Python
Java全栈开发
WEB前端+H5

请输入正确的手机号码

请输入正确的验证码

获取验证码

您今天的短信下发次数太多了,明天再试试吧!

提交

我们会在第一时间安排职业规划师联系您!

您也可以联系我们的职业规划师咨询:

小职老师的微信号:z_zhizuobiao
小职老师的微信号:z_zhizuobiao

版权所有 职坐标-一站式IT培训就业服务领导者 沪ICP备13042190号-4
上海海同信息科技有限公司 Copyright ©2015 www.zhizuobiao.com,All Rights Reserved.
 沪公网安备 31011502005948号    

©2015 www.zhizuobiao.com All Rights Reserved

208小时内训课程