什么是词法分析?
先写个例子。
1 | function t() { |
这里为什么,str1 的值,会是 undefined,因为JavaScript解释器在执行的时候有个词法分析的过程,词法分析的顺序决定了,这个值的事实结果。
那么词法分析的顺序是怎么样的呢?
1、先分析参数
2、再分析变量声明
3、最终分析函数声明
以下面的代码为例。
1 |
|
函数运行的瞬间,此函数会生成一个 Active Object,AO活动对象,一个函数作用于内能找到的所有变量,都在AO上。
分析结果: t.AO = {};
1、接收参数,以参数名为属性,参数值为属性值。
t.AO = {age:5};
2、 分析变量声明,在 AO 上形成一个属性,以变量名为属性名,值为undefined,如果 AO 上 已有同名属性,则不做任何影响。没有就略过。
3、分析函数声明,没有就略过。
最终:t.AO = {age:5};
如果函数的参数和函数内部定义的变量重名,会怎么样呢?
1 |
|
这个值的事实结果是 5 ,为什么会这样?我们前面不是说到,如果 AO 上有同名属性,这里不做任何影响的吗?原因在于,这里是分析过程,实际执行中,age = 5 这是一个赋值操作。
1 |
|
再进一步,如果同名的是一个函数呢?
1 |
|
可能你会以为是 3 ,其实,事实结果是 greet 函数,为什么呢?还是从词法分析来解释。
函数运行的瞬间,此函数会生成一个 Active Object,AO活动对象,一个函数作用于内能找到的所有变量,都在AO上。
分析结果: t.AO = {};
1、接收参数,以参数名为属性,参数值为属性值。
t.AO = {greet:3};
2、分析变量声明,没有略过。
3、分析函数声明,AO上如果有与此函数同名的属性,则会被此函数覆盖。
1 |
|
如果再进一步呢?比如把这里的函数声明,变成函数表达式?
1 |
|
这个函数的结果是 3 ,为什么?还是用前面的步骤来分析。
0、函数运行的瞬间,此函数会生成一个 Active Object,AO活动对象,一个函数作用于内能找到的所有变量,都在AO上。
1、接收参数,以参数名为属性,参数值为属性值。
t.AO = {greet:3}
2、分析变量声明,发现AO存在greet属性,不做任何影响。 t.AO = {greet:3}
3、分析函数声明,没有略过。
所以,结果为 3.
但是如果,改成这样
1 |
|
结果是 function ,因为这里的AO对象已经被改变。
再来看一个例子。
1 |
|
分析外层,a 函数
a.AO = {}
1 、分析参数,a.AO = {b:1}
2、分析var,略过
3、分析函数声明,a.AO = {b:function (b){alert(b)}};
执行
alert(b); a.AO.b = function(){}
分析内层 b 函数
b.AO = {}
1 、分析参数,略过
2、分析var,略过
3、分析函数声明,略过
alert(b);b.AO = {};
因为 b函数的 AO 对象中没有这个值,所以,要向上在 a.AO 上去拿。
故结果,都是函数。
函数声明与函数表达式
函数声明与函数表达式,有两个方面的区别,一方面是函数表达式的优先级别会比函数声明高,另一个是函数表达式是有返回值的。
1 |
|
June 10, 2018