0

I've seen a couple of questions that bear resemblance to mine ([1], [2]), but these seem to not quite hit what I'm after.

Example code:

function test(argument1) {
  sendToServer(argument2, function(callbackArgument1) {
    // Accessing argument1 here
  });
}

In the above example, I would like to access an argument (argument1) inside a callback function. Of course this is possible by passing argument1 as an argument in sendToServer(), and pass it around in that function, and eventually send it back in the callback, similar to callbackArgument1, but with more than 1 callback, this quickly gets extremely overwhelming and makes code very hard to read, especially if argument1 is not required inside the sendToServer() code.

I have tested this setup, where I added an artificial 2 second delay on the server side code, with the following setup:

function test(argument1) {
  sendToServer(function() {
    console.log(argument1);
  });
}

My fear would be that calling test() in rapid succession would overwrite argument1, so test() is called quickly enough, all the callbacks end up with argument1 being the same.

When I tested it however by calling test("cb1"); and test("cb2"); in quick succession, it returned "cb1" after 2 seconds, and 2 more seconds later, it returned "cb2". Although this is pretty conclusive, something feels very off to me, and I feel like this would not work at all in other programming languages, and would be heavily frowned upon.

So: Is it acceptable to access arguments from (or variables defined inside) the parent function (test() in my case) in a callback?

Timmiej93
  • 1,328
  • 1
  • 16
  • 35
  • 1
    Yes, it's reliable. Each call to `test` gets its own execution environment with its own lexical environment object that the identifiers within it (parameters, variables) exist within. Any function created within `test` has a link to that environment object, and the environment survives as long as any of those functions survives (even when `test` returns). Different calls to `test` get their *own* environments, so there's no cross-talk. – T.J. Crowder Mar 16 '21 at 16:29
  • 1
    See the linked question's answers or my blog post [*Closures are not complicated*](http://blog.niftysnippets.org/2008/02/closures-are-not-complicated.html) (some of the spec terminology is outdated now, but the gist is unchanged). – T.J. Crowder Mar 16 '21 at 16:30
  • 1
    Note that if `argument1` is a reference to an object, and something modifies one or more of that object's properties, naturally your code will see those modifications. – T.J. Crowder Mar 16 '21 at 16:31

0 Answers0