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?
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?
Share Improve this question edited Oct 30, 2012 at 20:27 ixx asked Oct 30, 2012 at 20:03 ixxixx 32.3k41 gold badges137 silver badges237 bronze badges 15 | Show 10 more comments4 Answers
Reset to default 11The 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);
}
})();
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
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.
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!
foo
a parameter? – SLaks Commented Oct 30, 2012 at 20:05canvas
should never evaluate to undefined inside the callback. Thecanvas
variable cannot be re-assigned in the provided code (an object being mutated is another matter), and that particularconsole.log
would only run ifcanvas.mousedown
was valid (which impliescanvas
is not undefined). Thus, I call shenanigans. The reported behavior is either wrong or is not the whole story. – user166390 Commented Oct 30, 2012 at 20:10