变量未定义在闭包中?

时间:2012-10-30 20:03:21

标签: javascript jquery variables closures

我有这样的功能:

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

我在页面的某个位置点击鼠标来调用foo。

为什么画布未定义?

4 个答案:

答案 0 :(得分:11)

调试器在使用之前可能不会在闭包中显示变量。

考虑这个例子,其中定义了一个变量但从未使用过:

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

相同的代码除了打印出变量而不是字符串文字:

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

答案 1 :(得分:2)

问题在于:

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

我没时间调查确切的原因。我的猜测是编译器在匿名函数的开头放置一个“var canvas”声明,这样在控制台输出时该变量是未定义的。否则还不明白。

答案 2 :(得分:2)

一旦你给出了整个代码示例,你自己的答案是正确的。你遇到了一个被称为“变量提升”的Javascript怪癖。您的代码被解释为:

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;
            //...
        }
    });
}

请参阅:

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

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

答案 3 :(得分:0)

只想确认在铬合金中,查理所说的是正确的。在使用调试器语句时,我需要在闭包内使用它之前引用有问题的变量!