简体   繁体   中英

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. 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.

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. Sorry!

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

Yes, you can - in javascript everything is possible - here is the fiddle 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.

You do have access to notGlobalVariable inside of myOtherFunction . However you're only assigning myOtherFunction and never invoking it. Note that you'll have to invoke myOtherFunction inside of myFunction .

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

}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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