Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

Already on GitHub? Sign in to your account

Closure isn't allowed to access outer scope #61

Closed
molily opened this Issue Feb 24, 2011 · 6 comments

Comments

Projects
None yet
3 participants

molily commented Feb 24, 2011

I'm basically using this pattern to build a closure:

var Liquid = {};
Liquid.Stage = function () {};
Liquid.Stage.prototype.getRenderer = function () {
  function renderer () {
    stage.doSomething();
  }
  var stage = this;
  return renderer;  
};
Liquid.Stage.prototype.doSomething = function () {};

This is a form of manual function binding which allows me to use renderer with setTimeout while accessing stage. I'm not using Function.prototype.bind here because this could double the function calls when using renderer.
(Full source at https://github.com/molily/liquid/blob/master/liquid.stage.render.js)

I get the error
Line 5 stage.doSomething();
'stage' is not defined.

This is a closure obviously. Doesn't JSHint recognize that the variable is defined in the outer function scope?

This is because you are using a variable before it is technically defined in the scope. If you were to place var stage = this; above the function declaration you would not have this error.

Liquid.Stage.prototype.getRenderer = function () {
  var stage = this;
  function renderer () {
    stage.doSomething();
  }
  return renderer;  
};

molily commented Feb 24, 2011

I moved the FD to the top because JSHint said so (“Inner functions should be listed at the top of the outer function.”). In my original code the FD was on the bottom of the outer func. Var declarations and FDs are hoisted anyway, so “technically” their position is arbitrary.This is all valid ECMAScript. As already mentioned in other tickets JSHint does not support FD hoisting.

If JSHint requires the order variable declarations > function declarations > other statements, it's okay as a coding guideline. Then, a better error message that just “is not defined” in this case would be helpful.

Totally agree errors should not be thrown in your specific instance.

Had you done

var renderer = function() {

I would then disagree.

Owner

valueof commented Feb 24, 2011

I feel like this is the same issue as #29. It is not that JSHint requires any order of variables, it is just that it does not know about the variable at the moment.

Anton, yeah they are both exhibiting the exact same behavior. This is a problem with the interpreter and I think the only way to remedy it is to account for all function declarations, I haven't delved enough into the source to tell when scope is entered and to check for said declarations.

Owner

valueof commented Feb 25, 2011

Okay, I am going to close this ticket then as a duplicate of #29.

This issue was closed.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment