2012-12-12 166 views
5

以下代码在书Head First jQuery中提供。变量未定义,有时

function lightning_one(t) { 
$("#lightning1").fadeIn(250).fadeOut(250); 
setTimeout("lightning_one()", t); 
}; // end lightning_one 

它被这条线调用。

lightning_one(3000); 

所观察到的行为是闪电淡入和出一次,等待3秒,淡入和淡出一遍,然后继续到淡入​​和淡出。 Firebug显示没有JavaScript错误。

我明白为什么我看到我所看到的。我想我会尝试保持3秒的间隔,所以我改变了这一点:

setTimeout("lightning_one()", t); // nothing in the brackets 

这样:

setTimeout("lightning_one(t)", t); // t is in the brackets 

当我刷新页面,闪电淡入和淡出一次。 Firebug告诉我变量t是未定义的。

我的问题是,如果在我改变之后变量t没有被定义,那么在我改变它之前,命令是如何运行没有错误的?它仍然有一个名为t的变量。

更多信息

谢谢大家谁写的意见和解答。根据记录,在“结束”文件夹,代码变成这样:

lightning_one(); 

    function lightning_one(){ 
$("#container #lightning1").fadeIn(250).fadeOut(250); 
setTimeout("lightning_one()",4000); 
    }; 

我还没说完适用章又是那么我不知道如果代码变化被建议以后。如前所述,这可能不是那里最好的书。然而,这是我买的,我从中学习jQuery的基础知识。

+4

他们真的把一个字符串传给'setTimeout'?把那本书扔得很远。 – Bergi

+0

我在想同样的事情:我认为用这种方式调用函数是一种不好的习惯......不是应该在书中教授的东西! – jahroy

+0

当我试图自己找到答案时,我看到了很多单词。调用不带引号的函数是我不成功的一个努力。尽管如此,我仍然认为准确的报价是最好的选择。 –

回答

6

因为setTimeout作为字符串的第一个参数是eval -ed,这意味着它将查看未定义其中t的函数的外部范围。第一个没有问题,因为你没有在调用中使用任何变量,但第二个不是因为t没有在函数范围之外定义。它实际上是本地的。

建议:根本不要使用eval。实际上,你不需要字符串参数。使用函数表达式:

setTimeout(function() { 

    lightning_one(t); 

}, t); 
2

工作:

setTimeout(function() { lightning_one(t); }, t); 

我敢肯定,从一个字符串调用的函数(并使其得到评估)是一种不好的做法,应该是避免。

+0

这个答案确实有效。 –