我有这样的功能:
function foo(canvas) {
canvas.mousedown(function(e) {
console.log(canvas); //undefined
});
}
我在页面的某个位置点击鼠标来调用foo。
为什么画布未定义?
答案 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)
只想确认在铬合金中,查理所说的是正确的。在使用调试器语句时,我需要在闭包内使用它之前引用有问题的变量!