javascrip 词法分析详解
JavaScript的高级知识---词法分析
词法分析
词法分析方法:
js运行前有一个类似编译的过程即词法分析,词法分析主要有三个步骤:
- 分析参数
- 再分析变量的声明
- 分析函数说明
- 函数在运行的瞬间,生成一个活动对象(Active Object),简称AO
- 分析参数
具体步骤如下:
- 函数接收形式参数,添加到AO的属性,并且这个时候值为undefine,例如AO.age=undefine
- 接收实参,添加到AO的属性,覆盖之前的undefine
- 分析变量声明,如var age;或var age=23;
- 如果上一步分析参数中AO还没有age属性,则添加AO属性为undefine,即AO.age=undefine
- 如果AO上面已经有age属性了,则不作任何修改
- 分析函数的声明,如果有function age(){}
把函数赋给AO.age ,覆盖上一步分析的值
代码例子1
这样我们先通过一段代码来理解词法分析:
<script>
function t1(age) {
console.log(age);
var age = 27;
console.log(age);
function age() {}
console.log(age);
}
t1(3);
</script>
词法分析阶段:
- 首先形成Active Object即AO对象
- 第一步:分析形式参数
AO.age = undefine
传入实参即对AO.age=undefine进行覆盖:
AO.age = 3
- 第二步:分析局部变量
存在var age = 27;
这个时候遵循如果AO.age存在值则不作任何修改,按照第一步分析的最后结果AO.age = 3,所以这里不作任何修改即:
AO.age = 3
- 第三步:分析函数的声明,
因为函数中存在function age(){}函数
所以按照规则应该将函数赋值给AO.age覆盖第二步分析的AO.age = 3即:
AO.age = function age(){}
执行阶段
执行t1函数,到console.log(age)时,词法分析的最后AO.age= function age(){},所以会打印:
function age(){}
var age=27;给age赋值27
到第二个console.log(age)这个时候age已经重新被赋值27,所以这个时候会打印:
27
function age() 并没有调用所以并不会执行
到第三个console.log(age)这个时候age的值并没有被再次修改,所以这个时候会打印:
27
运行js查看结果如下与我们分析的完全相符:
代码例子2
<script>
function t1(age) {
var age;
console.log(age);
var age = 23;
console.log(age);
function age() {}
console.log(age);
}
t1(22)
</script>
和上面的词法分析过程一样
词法分析阶段:
- 首先形成Active Object即AO对象
- 第一步:分析形式参数
AO.age = undefine
传入实参即对AO.age=undefine进行覆盖:
AO.age = 22
- 第二步:分析局部变量
第一步中最后得到AO.age = 22
所以这里var age;以及var age =23 ,因为AO.age属性已经存在值,所以这个时候遵循如果存在则不作任何修改,即:
AO.age = 22
- 第三步:分析函数的声明,
因为函数中存在function age(){}函数
所以按照规则应该将函数赋值给AO.age覆盖第二步分析的AO.age = 22即:
AO.age = function age(){}
执行阶段
执行t1函数,到console.log(age)时,词法分析的最后AO.age= function age(){},所以会打印:
function age(){}
var age=23;给age赋值23
到第二个console.log(age)这个时候age已经重新被赋值23,所以这个时候会打印:
23
function age() 并没有调用所以并不会执行
到第三个console.log(age)这个时候age的值并没有被再次修改,所以这个时候会打印:
23
运行js查看结果如下与我们分析的完全相符:
代码例子3
<script>
function t1(age) {
var age;
console.log(age);
age = 23;
console.log(age);
function age() {
console.log(age);
}
age();
console.log(age)
}
t1(22)
</script>
词法分析阶段:
- 首先形成Active Object即AO对象
- 第一步:分析形式参数
AO.age = undefine
传入实参即对AO.age=undefine进行覆盖:
AO.age = 22
- 第二步:分析局部变量
第一步中最后得到AO.age = 22,所以这里遵循,如果AO.age存在值则不作任何修改即:
AO.age = 22
- 第三步:分析函数的声明
因为函数中存在function age(){console.log(age)}函数
所以按照规则应该将函数赋值给AO.age覆盖第二步分析的AO.age = 22即:
AO.age = function age(){console.log(age)}
执行阶段
执行t1函数,到console.log(age)时,词法分析的最后AO.age= function age(){console.log(age)},所以会打印:
function age(){console.log(age)}
age = 23,这个时候会覆盖原来的function age(){console.log(age)},所以第二个console.log(age)会打印:
23
function age() 是一个函数表达式,所以不会做任何操作
age() 这个时候的age还是23,并不是函数表达式,所以这里会报错
运行js查看结果如下与我们分析的完全相符:
这里的提示错误确实也是说age不是一个函数
代码例子4
<script>
function t1(age) {
var age;
console.log(age);
function age() {
console.log(age);
}
age();
console.log(age);
}
t1(23)
</script>
词法分析阶段:
- 首先形成Active Object即AO对象
- 第一步:分析形式参数
AO.age = undefine
传入实参即对AO.age=undefine进行覆盖:
AO.age = 23
- 第二步:分析局部变量
第一步中最后得到AO.age = 23,所以这里遵循,如果AO.age存在值则不作任何修改即:
AO.age = 23
- 第三步:分析函数的声明
因为函数中存在function age(){console.log(age)}函数
所以按照规则应该将函数赋值给AO.age覆盖第二步分析的AO.age = 23即:
AO.age = function age(){console.log(age)}
执行阶段
执行t1函数,到console.log(age)时,词法分析的最后AO.age= function age(){console.log(age)},所以会打印:
function age(){console.log(age)}
function age() 是一个函数表达式,所以不会做任何操作
age()这个时候age是一个函数表达式,这里会执行function age(){console.log(age)},这个时候函数里console.log(age),age没有被修改所以还是function age(){console.log(age)},即打印:
function age(){console.log(age)}
最后一个console.log(age)这里的age没有被修改还是function age(){console.log(age)},所以会打印:
function age(){console.log(age)}
运行js查看结果如下与我们分析的完全相符:
代码例子5:
<script>
function t1(age) {
console.log(age);
var age = function () {
console.log(age)
}
age();
console.log(age);
}
t1(23);
</script>
词法分析阶段:
- 首先形成Active Object即AO对象
- 第一步:分析形式参数
AO.age = undefine
传入实参即对AO.age=undefine进行覆盖:
AO.age = 23
- 第二步:分析局部变量
第一步中最后得到AO.age = 23,所以这里遵循,如果AO.age存在值则不作任何修改即:
AO.age = 23
- 第三步:分析函数的声明
这里并没有函数声明表达式
所以最后分析的结果是:
AO.age = 23
执行阶段
执行t1函数,到console.log(age)时,词法分析的最后AO.age=23
所以第一个console.log(age)会打印
23
var age = function () {console.log(age)},这里将var = 23进行覆盖这个时候age是一个函数表达式
age() 正好调用function () {console.log(age)},这个时候这个函数里的console.log(age),age并没有修改还是一个函数表达式,所以会打印
function () {console.log(age)}
最后一个console.log(age)还是打印:
function () {console.log(age)}
运行js查看结果如下与我们分析的完全相符:
代码例子6:
<script>
function t1(age) {
console.log(age);
var age = function age() {
console.log(age);
}
age();
console.log(age);
}
t1(23);
</script>
代码例子6和代码例子5的分析基本一样,结果也是一样:
javascrip 词法分析详解的更多相关文章
- Hanlp分词之CRF中文词法分析详解
这是另一套基于CRF的词法分析系统,类似感知机词法分析器,提供了完善的训练与分析接口. CRF的效果比感知机稍好一些,然而训练速度较慢,也不支持在线学习. 默认模型训练自OpenCorpus/pku9 ...
- 转载:C/C++源代码到可执行程序的过程详解
C/C++源代码到可执行程序的过程详解 编译,编译程序读取源程序(字符流),对之进行词法和语法的分析,将高级语言指令转换为功能等效的汇编代码,再由汇编程序转换为机器语言,并且按照操作系统对可执行文件格 ...
- 常见 jar包详解
常见 jar包详解 jar包 用途 axis.jar SOAP引擎包 commons-discovery-0.2.jar 用来发现.查找和实现可插入式接口,提供一些一般类实例化.单件的生命周期 ...
- C编译器、链接器、加载器详解
摘自http://blog.csdn.net/zzxian/article/details/16820035 C编译器.链接器.加载器详解 一.概述 C语言的编译链接过程要把我们编写的一个c程序(源代 ...
- ctags使用说明详解
ctags使用说明详解 一.ctags是干什么的 ctags的功能:扫描指定的源文件,找出其中所包含的语法元素,并将找到的相关内容记录下来. 我用的是Exuberant Ctags 二.ctags可以 ...
- Oracle建立全文索引详解
Oracle建立全文索引详解1.全文检索和普通检索的区别 不使用Oracle text功能,当然也有很多方法可以在Oracle数据库中搜索文本,比如INSTR函数和LIKE操作: SELECT *FR ...
- 2. 知识图谱-命名实体识别(NER)详解
1. 通俗易懂解释知识图谱(Knowledge Graph) 2. 知识图谱-命名实体识别(NER)详解 3. 哈工大LTP解析 1. 前言 在解了知识图谱的全貌之后,我们现在慢慢的开始深入的学习知识 ...
- (转)总结之:CentOS 6.5 MySQL数据库的基础以及深入详解
总结之:CentOS 6.5 MySQL数据库的基础以及深入详解 原文:http://tanxw.blog.51cto.com/4309543/1395539 前言 早期MySQL AB公司在2009 ...
- [转]JavaScript异步机制详解
原文: https://www.jianshu.com/p/4ea4ee713ead --------------------------------------------------------- ...
随机推荐
- 用Golang为Python编写模块
Go里面需要显示的引入C模块, 让编译器支持生成动态链接库, 并且在代码中可以使用C语言的数据类型,这个至关重要. Calling Go code from Python code 摘取一个最简单例子 ...
- mysql视图总结
http://www.2cto.com/database/201508/427083.html 一. 视图概述 视图是一个虚拟表,其内容由查询定义.同真实的表一样,视图包含一系列带有名称的列和行数据. ...
- php_imagick超强的PHP图片处理扩展
php_imagick是一个可以供PHP调用ImageMagick功能的PHP扩展,使用这个扩展可以使PHP具备和ImageMagick相同的功能. ImageMagick是一套功能强大.稳定而且 ...
- 235D Graph Game
传送门 题目大意 https://www.luogu.org/problemnew/show/CF235D 分析 我们先考虑它是树的情况 我们设$event(x,y)$表示删除点x是y与x联通这件事对 ...
- Django rest_framework----序列化组件
生成hypermedialink serializer.pclass BookModelSerializers(serializers.ModelSerializer): class Meta: mo ...
- spring.net 集成nhibernate配置文件(这里暴露了GetCurrentSession 对于 CurrentSession unbond thread这里给出了解决方法)
我这里主要分成了两个xml来进行spring.net管理实际情况中可自己根据需要进行分类 Dao2.xml <?xml version="1.0" encoding=&quo ...
- Part3_lesson4---协处理器访问指令
1.什么是协处理器? CP15是协处理器, CP15的作用:系统控制协处理器CP15,它提供了额外的寄存器,这些寄存器用于配置和控制cache,MMU,保护系统,时钟模式,和其他的系统项,比如大小端操 ...
- Matlab和Python用于深度学习应用研究哪个好?
Matlab和Python都有一些关于深度学习的开源的解决方案(caffe\DeepMind\TensorFlow),基于哪个开展应用研究好?
- 使用 Windows Phone 8 文件和 URI 关联的自动启动应用
更详细,猛撸这里:http://msdn.microsoft.com/zh-cn/library/windowsphone/develop/jj206987(v=vs.105).aspx 在WMApp ...
- C# System.Threading.Timer 定时器
前提: 需要引入 System.Threading: 描述: 在很多时间我们都需要进行延迟执行,或是定时执行一些指定业务,这个时候使用 Timer 是最合适的,而且 Timer 是Cpu 级别处理对 ...