最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - variable undefined in closure? - Stack Overflow

programmeradmin15浏览0评论

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
  • Did you pass foo a parameter? – SLaks Commented Oct 30, 2012 at 20:05
  • 1 hm... yes, jsfiddle works. my code is more complex, will see what else can be causing the problem... – ixx Commented Oct 30, 2012 at 20:10
  • 6 canvas should never evaluate to undefined inside the callback. The canvas variable cannot be re-assigned in the provided code (an object being mutated is another matter), and that particular console.log would only run if canvas.mousedown was valid (which implies canvas 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
  • 1 @TML and others: Works fine for me in FF. It helps to set the background color on the canvas so you can see the damn thing! – Matt Burland Commented Oct 30, 2012 at 20:14
  • 1 Working fine for me in both Chrome and Firefox on Win32. What version of Chrome are you using? Did you actually click on the canvas? SnagIt Screenshot of Chrome result – TML Commented Oct 30, 2012 at 20:17
 |  Show 10 more comments

4 Answers 4

Reset to default 11

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);
  }
})();

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!

发布评论

评论列表(0)

  1. 暂无评论