词法分析

词法分析方法:

js运行前有一个类似编译的过程即词法分析,词法分析主要有三个步骤:

  • 分析参数
  • 再分析变量的声明
  • 分析函数说明

具体步骤如下:

  • 函数在运行的瞬间,生成一个活动对象(Active Object),简称AO
  • 分析参数
  1. 函数接收形式参数,添加到AO的属性,并且这个时候值为undefine,例如AO.age=undefine
  2. 接收实参,添加到AO的属性,覆盖之前的undefine
  • 分析变量声明,如var age;或var age=23;
  1. 如果上一步分析参数中AO还没有age属性,则添加AO属性为undefine,即AO.age=undefine
  2. 如果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的分析基本一样,结果也是一样:

总结

总之,按照上述最开始写的方法分析,都能分析出结果来

js的高级知识---词法分析的更多相关文章

  1. JavaScript的高级知识---词法分析

    JavaScript的高级知识---词法分析 词法分析 词法分析方法: js运行前有一个类似编译的过程即词法分析,词法分析主要有三个步骤: 分析参数 再分析变量的声明 分析函数说明 函数在运行的瞬间, ...

  2. 第十九篇 js高级知识---词法分析和AO 链

    上面一篇文章说了js的作用域链,这一节算是对上面的延申,有一个典型的例子,首先看原来的一段代码: var name = "test"; function t() { var b = ...

  3. js高级知识---词法分析和AO 链

    转载自https://www.cnblogs.com/OceanHeaven/p/4957704.html 上面一篇文章说了js的作用域链,这一节算是对上面的延申,有一个典型的例子,首先看原来的一段代 ...

  4. python成长之路【第十六篇】:JavaScript的高级知识---词法分析

    一.词法分析方法 js运行前有一个类似编译的过程即词法分析,词法分析主要有三个步骤: 分析参数 再分析变量的声明 分析函数说明 二.具体步骤如下: 函数在运行的瞬间,生成一个活动对象(Active O ...

  5. 第十八篇 js高级知识---作用域链

    一直有想法去写写js方面的东西,我个人是最喜欢js这门语言,喜欢的他的自由和强大,虽然作为脚本语言有很多限制的地方,但也不失为一个好的语言,尤其是在H5出现之后.下面开始说说js的方面的东西,由于自己 ...

  6. css+js+html基础知识总结

    css+js+html基础知识总结 一.CSS相关 1.css的盒子模型:IE盒子模型.标准W3C盒子模型: 2.CSS优先级机制: 选择器的优先权:!important>style(内联样式) ...

  7. 自理一遍android 高级知识

    之后按目录得复习巩固 目录: 客卓高级知识整理 1 移动架构 1.1 素养与基础 1.1.1 主流设计模式 创建型 行为型 结构型 1.1.2 UML 1.1.3 设计原则 1.1.4 AOP架构 1 ...

  8. DataBase MongoDB高级知识-易使用

    MongoDB高级知识-易使用 mongodb是一个面向文档的数据库,而不是关系型数据库.不采用关系模型主要是为了获取更好的扩展性.当然还有其他的一些好处. 与关系型数据库相比,面向文档的数据库不再有 ...

  9. DataBase MongoDB高级知识-易扩展

    MongoDB高级知识-易扩展 应用程序数据集的大小正在以不可思议的速度增长.随着可用宽带的增长和存储器价格的下跌,即使是一个小规模的应用程序,需要存储的数据也可能大的惊人,甚至超出了很多数据库的处理 ...

随机推荐

  1. JVM相关

    内存栅栏 1 what 说白了是一些cpu或编译器的一些同步指令 2 why cpu的cache快,而不去内存中取数据,在多线程并发中会读到cache的数据. 3 how 一般直接用关键字viloti ...

  2. 第二十六篇:两个SOUI新控件 ---- SListView和SComboView(借用Andorid的设计)

    SOUI原来实现的SListBoxEx的效率一直是我对SOUI不太满意的地方.包括后来网友实现的SListCtrlEx. 这类控件为每一个列表项创建一个SWindow来容纳数据,当数据量比较大(100 ...

  3. JSON.parse()和JSON.stringify()区别

    parse用于从一个字符串中解析出json对象,如: var str = '{"name":"huangxiaojian","age":&q ...

  4. WebForm增删改查

    最基本的,拼接字符串在Literal里面显示表,IsPostBack,增删改查基本,?传值 Request接收 LinQ to SQL类 在Default主页里面拖入Literal控件再加入一个按钮, ...

  5. win10 系统怎么获取最高管理员权限删除文件

    http://www.xitongcity.com/jiaocheng/win8_content_3473.html 很多win8.1系统用户在对磁盘文件进行清理时,经常会遇到“文件夹访问被拒绝,您需 ...

  6. TMS 例子63 分组,子node

    procedure TForm1.InitGrid; begin advstringgrid1.Grouping.MergeHeader := true; //这个什么作用没有是 advstringg ...

  7. ios8 设置单元格分割线无效

    原来: [self.tableView setSeparatorInset:UIEdgeInsetsMake(0, 0, 0, 0)];//分隔线紧贴左右边框 || [self.tableView s ...

  8. zeromq中两个dealer 通过一个router进行通信

    发现有童鞋不是很清楚ZMQ中的“请求-回复”模式中的ROUTER怎么用,所以简单介绍一下“请求-回复”模式的使用(最后付代码). 一.讲一讲 1.要使用zmq 通过一个router进行通信,你首先需要 ...

  9. HTML当中特殊字符的表示

    (回车换行) <br> (空格符)   &(AND符号) & <(左尖括号.小于号) < >(右尖括号.大于号) > °(度) ° •(间隔符) • ...

  10. PHP伪静态

    伪静态 从形式上看是一个静态地址,实际上还是访问的动态地址, 比如:访问:http://www.abc.com/news-sport-id123.html 实际上是:http://www.abc.co ...