简体   繁体   English

是否可以在函数中使用非全局变量?

[英]Is it possible to use non-global variables in function?

I've really looked all over for this and haven't found an answer that really explained this well... 我真的很满意这一点,并没有找到一个真正解释得很好的答案......

I know how to access a global variable from within a function. 我知道如何从函数中访问全局变量。

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

Now how do I access a variable one step up on the scope chain if it isn't global? 现在,如果它不是全局的,我如何在范围链上一步访问变量?

myGlobalVariable = [];

function myFunction() {

  var notGlobalVariable = "somedata";

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

}

I know I could do something like 我知道我可以做点什么

var notGlobalVariable = "somedata";

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

myOtherFunction(notGlobalVariable);

But calling the function that way only works if I have the value of notGlobalVariable readily available. 但是只有当notGlobalVariable的值可用时,调用该方式才有效。 I'd like do be able to globally call the function and have it always use the value originally held by notGlobalVariable without having to pass that value in. 我希望能够全局调用该函数,并始终使用notGlobalVariable最初持有的值,而不必传递该值。

Edit 编辑
Alright, I kinda jumped the gun on this one. 好吧,我有点跳过这一枪。 I though I was having a big variable scope issue, but apparently my issue was that in my specific code I was using the variable name arguments in place of notGlobalVariable , and as I should have known, arguments is shadowed and refers to the arguments passed in. I changed the name to args and it works fine. 我虽然有一个很大的变量范围问题,但显然我的问题是在我的特定代码中我使用变量名称arguments代替notGlobalVariable ,并且我应该知道, arguments被遮蔽并且引用传入的参数我将名称更改为args并且工作正常。 Sorry! 抱歉!

JavaScript does that automatically by creating closures. JavaScript通过创建闭包自动完成。

  • 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 (ie 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 myFunction可以看到myGlobalVariable
  2. the anonymous function stored in myOtherFunction can see myGlobalVariable and notGlobalVariable . 存储在myOtherFunction的匿名函数可以看到myGlobalVariablenotGlobalVariable

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. 您会看到callback函数可以访问thisIsPrivate因为它是在正确的范围内定义的,即使它执行的范围无法看到变量。

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. 同样, callback函数将无法看到notGlobalVariable ,即使该变量在执行回调的作用域中可见。

Note that you always must use var on any variable you define. 请注意,您始终必须对您定义的任何变量使用var Otherwise variables will be silently global which can and will lead to hard to fix bugs in your program. 否则变量将是静默全局的,这可能并且将导致难以修复程序中的错误。

Yes, you can - in javascript everything is possible - here is the fiddle http://jsfiddle.net/AZ2Rv/ 是的,你可以 - 在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]);

The problem of the OP laid actually in the code he didn't posted, but this sample code answers the original question - closures still work in javascript as expected. OP的问题实际上是在他没有发布的代码中实现的,但是这个示例代码回答了原始问题 - 闭包仍然按照预期在javascript中工作。

You do have access to notGlobalVariable inside of myOtherFunction . 您可以访问notGlobalVariable内的myOtherFunction However you're only assigning myOtherFunction and never invoking it. 但是,您只是分配myOtherFunction并且从不调用它。 Note that you'll have to invoke myOtherFunction inside of myFunction . 请注意,您必须在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()

}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM