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而不必传入该值。

编辑
好吧,我在这个问题上有点过头了。我虽然有一个很大的变量范围问题,但显然我的问题是在我的特定代码中我使用变量名arguments代替notGlobalVariable,并且我应该知道,arguments它被遮蔽并引用传入的参数。我改变了的名称args,它工作正常。对不起!

4

3 回答 3

4

JavaScript does that automatically by creating closures.

  • Every function creates its own scope.
  • Scopes are nested, since functions can be defined within functions.
  • Every new nested scope ("function") can see all the variables that were defined in any parent scope at the point of its (i.e that new function's) creation. This is called a closure.
  • Every variable from any parent scope is "by reference" - child scopes ("functions") always see their current values.
  • The point in time when the function runs does not matter, only the point in time when it was declared (see first example).
  • The scope where a function runs in does not matter, only the scope a function was defined in (see second example).

Here

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"]

you create two scopes:

  1. myFunction can see myGlobalVariable
  2. the anonymous function stored in myOtherFunction can see myGlobalVariable and notGlobalVariable.

Now assume a small change:

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"]

You see that the callback function has access to thisIsPrivate because it was defined in the right scope, even though the scope it is executed in cannot see the variable.

Likewise the callback function will not be able to see notGlobalVariable, even though that variable is visible in the scope where the callback is executed.

Note that you always must use var on any variable you define. Otherwise variables will be silently global which can and will lead to hard to fix bugs in your program.

于 2013-06-28T15:42:04.700 回答
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 中按预期工作。

于 2013-06-28T15:22:08.657 回答
1

您确实有权notGlobalVariable访问myOtherFunction. 但是,您只是分配myOtherFunction而不是调用它。请注意,您必须myOtherFunctionmyFunction.

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()

}
于 2013-06-28T15:22:26.910 回答