3

Normally, to create a closure, you create it inside another function, and it gets the scope of its parent:

var parent = function(){
  var a = "works!";
  var subfunction(){
    console.log(a); // "works!"
  }
  subfunction();
}

I'm trying to figure out a way to emulate this closure behavior with a function that is defined outside of the parent function. I know this is possible using parameters:

var parent = function(){
  var a = "hello";
  subfunction(a);
}
var subfunction(a){
  console.log(a); // works, but because it's a param
}

I'm trying to figure out if there's a way to do it without having to explicitly set all parameters. I was initially thinking I'd be able to pass the functions local scope object as a parameter

var parent = function(){
  var a = "hello";
  subfunction(localScope);
}
var subfunction(localScope){
  console.log(localScope.a); // not going to work this way
}

... but I've since discovered that it's impossible to get a reference to a function's scope. Is there some other way to emulate a closure outside of the actual scope of a function?

Community
  • 1
  • 1
brentonstrine
  • 21,694
  • 25
  • 74
  • 120
  • [Possibly of interest](https://en.wikipedia.org/wiki/Scope_%28computer_science%29#Lexical_scope_vs._dynamic_scope) - JavaScript is a lexically-scoped language. – Pointy Feb 22 '16 at 20:37

1 Answers1

2

No, closures in JS are always lexical (i.e. referring to their parent scope).

If you want to create a closure with an explicitly set environment, you may of course use a helper function for that:

function unrelated() {
    var closure = makeClosure("hello");
    closure();
}
unrelated();

function makeClosure(a) {
    return function() { // closes only over `a` and nothing else
        console.log(a);
    }
}

That's as close a you will get to an "external closure". Notice you can only pass values to makeClosure, not references to local variables. Of course you could make objects and pass the reference to them around, and with with (not recommended!) you could even make them look like variables.

Bergi
  • 630,263
  • 148
  • 957
  • 1,375
  • This seems to be almost exactly the same as my second example, except instead of passing `a` as a param, you are passing the _value_ of `a` as a param. – brentonstrine Feb 22 '16 at 20:42
  • @brentonstrine: The difference (which brings it closer to the original closure) is that I'm passing the value when *creating* the function, not when *calling* it. – Bergi Feb 22 '16 at 20:44
  • This is terrible, how it got upvotes is beyond me. Yes Bergi, it is different from his second example, but it is not what he asked for, not even remotely – QBM5 Feb 22 '16 at 20:47
  • @QBM5: Not sure how this solution is terrible? And while I'm not exactly sure what he is asking about or why (and what problem he has), I think my first sentence does answer the question. – Bergi Feb 22 '16 at 20:51