js词法分析

Javascript中的函数“在定义它们的作用域里运行,而不是在执行它们的作用域里运行”,这是权威指南里抽象而精辟的总结。

分三步

1 分析参数

2分析变量声明

3分析函数声明

具体步骤

0: 函数运行前的1瞬间, 生成 Active Object (活动对象),下称AO       活动对象(activeObject)可理解为一个记录当前执行的方法【内部执行信息】的对象,记录内部变量集(variables)、内嵌函数集(functions)、实参(arguments)、作用域

链(scopeChain)等执行所需信息,其中内部变量集(variables)、内嵌函数集(functions)是直接从语法分析树

 
1:
   1.1 函数声明的参数,形成AO的属性,值全是undefined,
   1.2 接收实参,形成AO相应的属性的值

2把声明的参数,放到活动对象的属性里,形成active object的属性,值全是undefined

3分析变量的声明,(前面加var)如var age 如果AO上已经有age属性则不做任何修改,如果AO上没有age属性,则添加AO属性,因此事没赋值,因此是undefined

4分析函数声明, 如function foo(){}, 则把函数赋给AO.foo属性

  注,如果在此之前foo属性已经存在怎么办------答:无情覆盖

 

 1 function t(age){
 2     alert(age);    
 3 }
 4 
 5 t(5); // 5
 6 t(); //undefined
 7 
 8 /*
 9 词法分析过程
10 AO {age:undefined}
11 
12 
13 运行过程
14 t(5)  -->AO.age = 5; alert(AO.age) ;//5
15 t()  -->AO.age  ;// 没得到赋值,还是undefined
16 */

 

稍微难点的

在函数内部声明var age = 99 ;

function t2(age){
    var age=99;
    alert(age);
}
t(5);//  99

分析过程

1 形成AO={}

2 分析形参。AO={age;undefined}

3分析var age 发现AO已经有age属性,因此不做任何修改

执行过程

var age =99;

alert(age);

 

 

再看这个容易错的题

function t3(greet) {
    var greet = 'hello'; // 试着把这一句变成 var greet;再做分析
    alert(greet);

    function greet() {
    }

    alert(greet);
}

t3(null);  // hello hello

/*
词法分析过程:
0: AO = {}
1: 
   1.1 分析参数 AO = {greet:undefined}
   1.2 分析参数 AO = {greet:null}
2: 分析greet变量声明,AO已经有greet属性,因此不做任何影响
3: 分析greet函数声明, AO.greet = function() {} , 被覆盖成函数


执行过程:
greet = 'hello';
alert(greet);
alert(greet);
*/

* 函数声明与函数表达式的区别

表达式必有返回值,把返回值(即匿名函数)赋给了一个变量.

 

posted @ 2014-11-25 20:30  王孙将归  阅读(181)  评论(0编辑  收藏  举报