2

I was debugging a jQuery code with Chrome and I got stuck on a scope problem.
This is my code:

var foo = "bar";
$.each([1], function(key, value) {
    console.log(foo);
    console.log("Test");
});

If I put a breakpoint before the second console.log, I can see foo among the Closure variables. But if I comment the line before (thus NOT outputting foo to the console), when I stop at the breakpoint the foo variable is missing (in fact, a whole Closure level of variables is missing). I tested this code both in Chrome and in Firefox, it has the same odd behaviour.
It's like outputting the variable to the console "stores" it in a new Closure level and exposes those variables.

Am I missing something?

EDIT: Bergi pointed me to the right answer (see garbage collection with node.js).
To summarize it here, when I comment the first console.log, foo variable is never used inside theeach callback and V8 compiler immediately makes it unreachable. If I want to inspect it while debugging I have to use it somewhere, like:

var foo = "bar";
$.each([1], function(key, value) {
    console.log("Test");
    function test() { console.log(foo); }
});

This way if I stop at the first console.log, I can inspect the variable as expected.
I could also use the with statement (but it's deprecated so this probably isn't the right way to approach it ^_^):

var foo = "bar";
with(foo) {
    $.each([1], function(key, value) {
        console.log("Test");
    });
}

The linked answer is about V8, but I think SpiderMonkey (Firefox's JS engine) behaves the same way.

Community
  • 1
  • 1
goffreder
  • 503
  • 3
  • 17
  • A dummy array to have at least one iteration of the anonymous function. – goffreder May 28 '14 at 13:11
  • ``var array = new Array(); arr.push(1);`` then pass arr in each – Ehsan Sajjad May 28 '14 at 13:13
  • What do you mean by missing? – PeterKA May 28 '14 at 13:14
  • Check this http://jsfiddle.net/jD6ay/ your question is very unclear. – Wilfredo P May 28 '14 at 13:14
  • 2
    I'm sorry but I think you're missing the point, the array I'm iterating is not important, I probably chose a misleading example but this is the exact situation I'm facing, so I prefered to report it as close as possible to the "real" problem ^_^ – goffreder May 28 '14 at 13:15
  • @EhsanSajjad It's an array, why on earth would you suggest `new Array()` and a push when there's a cleaner, quicker, canonical way to create an array? – Dave Newton May 28 '14 at 13:15
  • Ehran, [1] is perfectly acceptable. – Andy May 28 '14 at 13:15
  • 2
    I think the problem here is that foo isnt really defined in that context, just accessible from within it, your debuger probably adds it to the list of defined variables when you access it. – cernunnos May 28 '14 at 13:17
  • @WilfredoP My problem occurs when I'm debugging, I don't think jsfiddle will help me (but of course I can be wrong on this) – goffreder May 28 '14 at 13:18
  • 3
    The reason you dont see the variable in the console is because its not being used inside the function. "Just because you cant see it doesnt mean its not there." – Pedro Estrada May 28 '14 at 13:18
  • @PedroEstrada so this is a debugger problem? when I debug it's very useful to know which variables I have access to at some point and which variables I don't, even if I haven't used them yet. is this a known bug of ChromeDevTools/Firebug maybe? – goffreder May 28 '14 at 13:23
  • @goffreder its not necessarily a bug imo. I mean if you think about it. If you had 30 global variables and youre debugging a simple function, i dont want to see all 30 global variables in my console. – Pedro Estrada May 28 '14 at 13:31
  • @goffreder: `foo` must be present. Its scope may depend upon where you defined that variable. In debugger, you can check it under `scope variables` section. It may be present in `closure or global` scope. Also, in order to check whether variable scope is present or not, you can simply check it in `watch expression` section when execution stops at your desired breakpoint. – Mohit Pandey May 28 '14 at 13:36
  • @MohitPandey I also thought that `foo` should have been present, it just isn't. If I type `foo` in the console it says` ReferenceError: foo is not present` (in Chrome) – goffreder May 28 '14 at 13:41
  • @PedroEstrada I don't want to "see" them all at once either. But I'm expecting that if I type the name of a variable I have access to at this point in the console, I should see it. I shouldn't be forced to use it before I can inspect it... – goffreder May 28 '14 at 13:43
  • @goffreder: I reproduce it and the reason mighty be `var foo='bar'`. If you define it as a global variable `foo='bar';`, then you will able to get it. I don't know whats the exact issue. But yes, its a step forward in direction to resolve it. – Mohit Pandey May 28 '14 at 13:53

0 Answers0