ixx
ixx

Reputation: 32273

variable undefined in closure?

I have a function like this:

function foo(canvas) {
    canvas.mousedown(function(e) {
        console.log(canvas); //undefined
    });
}

I'm calling foo on mouse click in a certain spot of the page.

Why is canvas undefined?

Upvotes: 5

Views: 4692

Answers (4)

Charlie
Charlie

Reputation: 9108

The debugger may not show the variables in the closure until they are used.

Consider this example where the a variable is defined but never used:

(function() {
  var x = 1;
  $(function () {
    debugger; // debugger stopped here, `x` is `undefined` in Chrome and IE but `1` in Firefox
    console.log("hi");
  }
})();

Same code except the variable is printed out instead of the string literal:

(function() {
  var x = 1;
  $(function () {
    debugger; // debugger stopped here, all three browsers show `x` as `1`
    console.log(x);
  }
})();

Upvotes: 11

PlusPlus
PlusPlus

Reputation: 1

Would just like to confirm that in chrome, what Charlie said is correct. I needed to make a reference to the variable in question before I could use it within the closure, when using the debugger statement!

Upvotes: 0

Johann
Johann

Reputation: 4373

Your own answer is correct, once you gave the whole code example. You encountered a quirk of Javascript known as "variable hoisting." Your code is interpreted as:

function foo(canvas) {
    canvas.mousedown(function(e) {
        var i, canvas; //variable declarations moved to top of function scope
        console.log(canvas); //undefined
        //...
        for (i in array) {
            canvas = array[i].canvas;
            //...
        }
    });
}

See:

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/var#var_hoisting

http://www.adequatelygood.com/JavaScript-Scoping-and-Hoisting.html

Upvotes: 4

ixx
ixx

Reputation: 32273

The problem was this:

function foo(canvas) {
    canvas.mousedown(function(e) {
        console.log(canvas); //undefined
        //...
        for (var i in array) {
            var canvas = array[i].canvas;
            //...
        }
    });
}

I haven't time to investigate the exact reason. My guess is that the compiler puts a "var canvas" declaration at the start of the anonymous function, such that the variable is undefined when output in the console. Otherwise don't understand it yet.

Upvotes: 2

Related Questions