3

我有这样的功能:

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

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

为什么画布未定义?

4

4 回答 4

11

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

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

(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);
  }
})();
于 2015-03-30T16:46:23.633 回答
2

问题是这样的:

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

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

于 2012-11-11T22:46:05.923 回答
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

于 2013-12-27T18:42:27.510 回答
0

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

于 2015-07-28T08:20:33.793 回答