Javascript范围问题:未识别变量

时间:2011-09-03 07:19:27

标签: javascript function scope

我有两个函数,一个函数调用另一个函数。

下面是我创建的代码结构的简单类比:

function test1(){
    alert(a);//a is not identified here even when test1() is called under test2 which has a defined in scope
    alert(b);//b is identified here
}

function test2(){
    var a       =       'a';//Defining a
    test1();//Calling test1()
}
var b   =   'b';
test2();

根据上面的代码,函数test1()能够识别变量b但不能识别变量a。

我的问题是,为什么变量a不在test1函数的范围内,即使我们在test2()中调用test1()来定义变量a?

提前致谢。

5 个答案:

答案 0 :(得分:3)

你对变量范围的期望是错误的,

根据您的代码b是2个函数的全局变量,而a仅在test2函数的范围内,因为它是使用test2定义的, 如果您想要符合预期的内容,可以在此test1范围内定义test2函数,

function test2(){
    var a       =       'a';
    test1();
  function test1(){
      alert(a);
      alert(b);
   }
}
var b   =   'b';
test2();

答案 1 :(得分:3)

函数在创建时记住它们的范围链,而不是在它们被调用时。

请注意b获取"hoisted",因此您的代码实际上是这样做的:

var b; // push b on scope chain

function test1(){ // store scope chain [b]
    alert(a);
    alert(b);
}

function test2(){ // store scope chain [b]
    var a; // push a on scope chain
    a = 'a';
    test1(); //Calling test1() which still has scope chain [b], not [b,a]
}
b   =   'b';
test2();

答案 2 :(得分:2)

JavaScript具有“功能范围”,这意味着函数中定义的任何内容在函数外部都不可见。因此变量'a'在test2之外是不可见的。但是,变量'b'是一个全局变量,因此它在每个范围内都可见。

函数作用域也意味着内部函数可以访问外部函数中定义的东西,但这里没有发挥作用... test1在test2中从调用但它不是内部函数test2的功能。要查看此操作,您需要在test2 ...

中定义test1函数的主体
function test2(){
    var a       =       'a';//Defining a
    test1();//Calling test1()

    function test1(){
        alert(a);//a is identified here because of function scope
        alert(b);//b is identified here because it's global
    }
}

答案 3 :(得分:2)

使用参数调用函数是一个好习惯。这将使您的代码易于阅读和维护。只需在函数中添加参数即可使代码正常工作:

function test1(a,b){
    alert(a);
    alert(b);
}

function test2(b){
    var a = 'a';
    test1(a,b);
}
var b = 'b';
test2(b);

如果您不想在函数声明中使用参数,解决方案是使用代码中的arguments object

function test1(){
    alert(arguments[0]);
    alert(arguments[1]);
}

function test2(){
    var a = 'a';
    test1(a,arguments[0]);
}
var b = 'b';
test2(b);

如果您愿意,可以制作arguments with default values。因为在JavaScript中你不能在函数参数列表中执行它,它在函数体中完成:

function test1(a,b){
    a = a || 'a';
    b = b || 'b';
    alert(a);
    alert(b);
}
function test2(b){
    var a = 'a';
    test1(a);//here b is not passed to the function and b will get the default value
}
var b = 'some new string for b';
test2(b);

住在jsfiddle

答案 4 :(得分:0)

根据您的功能,您已在函数“ test2()”中声明并定义变量“ a ”,因此变量“ a的范围“受限于该函数本身,访问该变量将返回” undefined “。但它不是全局声明和定义的变量“ b ”的情况,因此可以在脚本部分的任何位置访问它。

希望这会对你有所帮助。