Demo
var name = "test";
function t() {
alert(name);
var name = "test1";
alert(name);
}
t();
结果为:<1>undefined <2>test1
var name = "test";
function t() {
alert(name);
name = "test1";
alert(name);
}
t();
结果为:<1>test <2>test1
在js运行前会有一个类似编译的过程——词法分析。首先看下记法分析的过程,词法分析主要分三个步骤:
1、先分析参数
2、再分析变量的声明
3、分析函数说明
具体的步骤:
0:函数的在运行的瞬间,生成一个活动对象(Active Object)就是所谓的AO
1:分析参数
1-1:函数接收参数,添加到AO的属性上面,值全部都是undefine,如AO.age=undefine
1-2:接收实参,形成AO对应的属性值
2:分析变量声明,如var age,
2-1:如果AO上还没有age属性,则添加AO 属性,值是undefine
2-2:如果AO 上面已经有了age属性,则不做任何操作。
3:分析函数的声明,如果funcion foo(){},
3-1: 则把函数赋给AO.fooo,如果数据属性已经存在,则要被现在的新的值覆盖
下面开始分析上面修改1的执行的过程(自上崦下):
1、在window上面形成一个AO链,AO.name=undefine;
2、在函数的内部分析参数,函数没有参数,略过
3、在到变量声明阶段,在t函数的内部形成AO1,AO1.name=undfine;
4、分析函数声明,略过
执行过程:
1、首先是 在外层的AO.name=”test”
2、执行t函数,执行到console.log(name)时,函数内有name属性,就不会在到外面去寻找 执行输出undefine
3、执行赋值语句AO1.name=”test1”
4、输出当前的name值,”test1”;具体的步骤:
0:函数的在运行的瞬间,生成一个活动对象(Active Object)就是所谓的AO
总结:
//编译时先分析参数,再分析变量声明,再分析函数说明
//执行过程为先寻找函数外变量,再执行函数内部如果函数内部有该变量或方法则输出undefine或该方法,
//自上崦下匹配
var age = 88; //函数内部没相同变量或方法就执行
function t() {
alert(age); //一般输出整个函数或undefine 结果为:函数体
var age = 99;
alert(age); //99 如果age没赋值输出方法体 结果为:99
function age() {
}
var age = 55;
alert(age); //结果为:55
var age=function () {//==var age; age=25;不是真正的函数声明
console.log(age);
}
}
t(5);