javaScript函数中的活动对象

javascript中,代码的解析分为两个阶段,变量初始化阶段和代码执行阶段。

变量初始化阶段

  1. 函数参数(若未传入,则初始化值为undefined)
  2. 函数声明(若发生命名冲突,会覆盖)

    function foo(x){
        function x(){};//函数声明覆盖了参数x
        console.log(x); 
    }
    foo(34);     //输出'function x(){}'
  3. 变量声明(初始化变量值为undefined,若发生命名冲突,会忽略)

    function foo3(){
        function z(){};
        var z; //变量声明冲突,则忽略该声明。
        console.log(z);
    }
    foo3();//输出'function x(){}'

代码执行阶段

注意,函数变量初始化阶段和代码执行阶段是两个不同的阶段,代码执行阶段将按顺序给代码赋值。如下代码,虽然在变量初始化阶段,z会被函数声明覆盖,但等到代码执行阶段,z又重新被赋值为10。因此,最终z的输出结果仍然为10。

function foo2(){
    var z = 10;
    function z(){};
    console.log(z);
}
foo2(); //'10'
function foo4(x,y,x){
    function z(){};
    var z = 10;//在变量初始化阶段被忽略,在函数执行阶段覆盖z函数
    console.log(z);
}
foo4();//10

代码分析

function example(){
    console.log(x); //'function x(){}'
    var x = 10;
    console.log(x);//'10'
    x = 20;

    function x(){}
    console.log(x);

    if (true) {
        var a = 1;
    }else{
        var b = true;
    }

    console.log(a);//1
    console.log(b);//undefined
    console.log(c);//
};
example();//ReferenceError: c is not defined

如上代码,在变量初始化阶段,第一步,先初始化函数参数,此处没有传入任何参数,因此,初始化的参数个数为0。第二步,初始化函数声明,因此function x(){}的声明被提前。第三步,初始化变量声明,第一个变量为x,因为已经声明了同名函数x,因此变量x的声明被忽略;所以,只声明了变量a和b,在这一阶段,变量a和b的值都为undefined。
接着,进入代码执行阶段,代码将按顺序执行。第一句代码输出x,因为在初始化阶段,x已被声明为函数,因此会输出‘function x(){}’。第二句代码,会执行赋值操作,重新将x赋值为10。第三句代码再次输出x,则为‘10’。第四句代码重新将x赋值为20。第五句代码已经在变量初始化阶段完成了声明,因此此时将被忽略。第六句代码再次输出x,此时将输出‘20’。接下来为判断语句,因为条件为true,所以将变量a赋值为1,此时,没有对变量b进行赋值,所以,变量b的值仍为undefined。最后,输出a,为‘1’;输出b,值为‘undefined’。如果输出的是一个未声明的变量,如最后一句代码,输出c,则会报错:‘ReferenceError: c is not defined’。

你可能感兴趣的:(javaScript)