总结:html
js运行前有一个相似编译的过程即词法分析,词法分析主要有三个步骤:函数
把函数赋给AO.age ,覆盖上一步分析的值post
这样咱们先经过一段代码来理解词法分析:spa
<script> function t1(age) { console.log(age); var age = 27; console.log(age); function age() {} console.log(age); } t1(3); </script>
<script> function t1(age) { var age= function () {} console.log(age); var age = 27; console.log(age); console.log(age); } t1(3); </script>
AO.age = undefinecode
传入实参即对AO.age=undefine进行覆盖:htm
AO.age = 3对象
存在var age = 27;blog
这个时候遵循若是AO.age存在值则不做任何修改,按照第一步分析的最后结果AO.age = 3,因此这里不做任何修改即:ip
AO.age = 3it
由于函数中存在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查看结果以下与咱们分析的彻底相符:
<script> function t1(age) { var age; console.log(age); var age = 23; console.log(age); function age() {} console.log(age); } t1(22) </script>
和上面的词法分析过程同样
等价于:
<script> function t1(age) { var age= function () {}; console.log(age); var age = 23; console.log(age); console.log(age); } t1(22) </script>
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查看结果以下与咱们分析的彻底相符:
<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>
等价于:
<script> function t1(age) { var age= function age() { //函数表达式 console.log(age); }; console.log(age); //输出age函数 age = 23; console.log(age); //age是变量 age(); //报错 console.log(age) } t1(22) </script>
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不是一个函数
<script> function t1(age) { var age=function age() {
console.log(age); }
; console.log(age);
age();
console.log(age);
}
t1(23) </script>
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查看结果以下与咱们分析的彻底相符:
<script> function t1(age) { console.log(age); //23 var age = function () { console.log(age) } age(); //函数 console.log(age); //函数 } t1(23); </script>
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查看结果以下与咱们分析的彻底相符:
<script> function t1(age) { console.log(age); var age = function age() { console.log(age); } age(); console.log(age); } t1(23); </script>
代码例子6和代码例子5的分析基本同样,结果也是同样:
总之,按照上述最开始写的方法分析,都能分析出结果来