2013-06-28 67 views
3

我真的看了这么多,并没有找到一个真正解释这个问题的答案...是否可以在函数中使用非全局变量?

我知道如何从函数内部访问全局变量。

myGlobalVariable = []; 
function myFunction() { 
    myGlobalVariable.push("somedata"); 
} 

现在如何访问范围链上的一个变量,如果它不是全局的?

myGlobalVariable = []; 

function myFunction() { 

    var notGlobalVariable = "somedata"; 

    var myOtherFunction = function() { 
    myGlobalVariable.push(notGlobalVariable); // This is what I'd like to be able to do. 
    } 

} 

我知道我可以做这样的事情

var notGlobalVariable = "somedata"; 

var myOtherFunction = function(arg) { 
    myGlobalVariable.push(arg); 
} 

myOtherFunction(notGlobalVariable); 

但调用该方法只有当我有notGlobalVariable一应俱全工程价值的功能。我希望做能够在全球范围内调用函数,并将它总是使用最初由notGlobalVariable保存的值,而不必通过该值。

编辑
好吧,我还挺跳上这一枪。不过,我觉得我有一个很大的变量范围的问题,但显然我的问题是,在我的特定代码,我代替notGlobalVariable使用变量名arguments,并作为我应该知道,arguments被遮挡时,是指在传递的参数。我将名称更改为args,它工作正常。抱歉!

+3

这是什么问题?你的例子完美地工作。 –

+3

你的例子应该工作。也许你只是分配'myOtherFunction'而不是'myOtherFunction()'调用'myOtherFunction'' –

+0

http://jsfiddle.net/N4kfY/1/ - 适用于我。 –

回答

4

JavaScript通过创建闭包自动执行。

  • 每个函数都创建自己的作用域。
  • 范围是嵌套的,因为函数可以在函数中定义。
  • 每个新的嵌套范围(“函数”)都可以看到在任何父范围中(即新函数的)创建点处定义的所有变量。这被称为封闭。
  • 任何父范围的每个变量是“参照” - 子作用域(“功能”)总能看到它们的当前值。
  • 的时间点,当函数运行无所谓,只有在当它被宣布的时间点(见示例)。
  • 功能中运行的范围无关紧要,只有(参见第二个示例)中定义的功能范围为

这里

var myGlobalVariable = []; 

// define function => creates closure #1 
function myFunction() { 
    var notGlobalVariable = "somedata"; 

    // define function => creates closure #2 
    var myOtherFunction = function() { 
    myGlobalVariable.push(notGlobalVariable); 
    } 

    // execute function 
    myOtherFunction(); 
} 

myFunction(); // myGlobalVariable will be ["somedata"] 

创建两个作用域:

  1. myFunction可以看到myGlobalVariable
  2. 存储在myOtherFunction可以看到myGlobalVariablenotGlobalVariable匿名函数。

现在假设一个小的变化:

var myGlobalVariable = []; 

// define function => creates closure #1 
function myFunction(callback) { 
    var notGlobalVariable = "somedata"; 

    // define function => creates closure #2 
    var myOtherFunction = function() { 
    myGlobalVariable.push(callback()); 
    } 

    // execute function 
    myOtherFunction(); 
} 

// define function => creates closure #3 
function foo() { 
    var thisIsPrivate = "really"; 

    // define function => creates closure #4 
    return function() { 
    return thisIsPrivate; 
    } 
} 

myFunction(foo()); // myGlobalVariable will be ["really"] 

你看到callback功能访问thisIsPrivate,因为它是在正确的范围定义,即使范围内,可以执行看不到变量。

同样,callback函数将无法看到notGlobalVariable,即使该变量在执行回调的作用域中可见。

请注意,您总是必须在您定义的任何变量上使用var。否则,变量将会默默地全局化,这会导致难以修复程序中的错误。

+0

+1有关范围和封闭的详细说明。如果可以的话,我会给+100。现在我很尴尬与我简洁的回答:( – ElmoVanKielmo

1

是的,你可以 - 在JavaScript中一切皆有可能 - 这里是小提琴http://jsfiddle.net/AZ2Rv/

myGlobalVariable = []; 

function myFunction() { 

    var notGlobalVariable = "somedata"; 

    // The following assigns a function to a variable 
    var myOtherFunction = function() { 
    myGlobalVariable.push(notGlobalVariable); 
    } 

    // The following line was missing in the code in the question so the function 
    // was never called and `notGlobalVariable` wasn't pushed into `myGlobalVariable` 
    myOtherFunction(); 
} 

// And just to test if it works as expected 
myFunction(); 
alert(myGlobalVariable[0]); 

的代码实际上奠定了OP他没有公布的问题,但此示例代码回答原如预期的那样,问题 - 关闭仍然可以在JavaScript中工作。

+0

downvote的任何解释?它的工作 - 小提琴附加。 – ElmoVanKielmo

+1

我不认识人,但它看起来和OP已经有的一样(除了添加的函数调用) –

+0

而这个缺失的调用正是导致'notGlobalVariable'不能被推入'myGlobalVariable'的原因...... – ElmoVanKielmo

1

您有权访问myOtherFunction中的notGlobalVariable。但是,您只分配myOtherFunction并且从不调用它。请注意,您必须在myFunction之内调用myOtherFunction

function myFunction() { 

    var notGlobalVariable = "somedata"; 

    var myOtherFunction = function() { 
    myGlobalVariable.push(notGlobalVariable); // This is what I'd like to be able to do. 
    } 
    //Invoke myOtherFunction() 
    myOtherFunction() 

} 
+0

@ElmoVanKielmo您收到了赞成票或者是因为您没有解释您的答案,或者是因为人们回复了您的意见。他们来来往往是一个有点卑鄙的国际海事组织......即使你不打算这样做。 –

相关问题