Javascript变量意外未定义

Javascript变量意外未定义,javascript,scope,undefined,Javascript,Scope,Undefined,对于此代码块: if(!skipit) { var update_argument=''; if (document.formname.fieldname) { update_argument=document.formname.fieldname[document.formname.fieldname.selectedIndex].value; } window.setTimeout('updatepcols(upda

对于此代码块:

  if(!skipit)
    {
    var update_argument='';
    if (document.formname.fieldname)
      {
        update_argument=document.formname.fieldname[document.formname.fieldname.selectedIndex].value;
      }
    window.setTimeout('updatepcols(update_argument)',250);
       return false;
    }
我在setTimeout调用中得到一个错误,即“update_参数”未定义。当我将分配空字符串值的行从“var”更改为“window”时,错误消失了,代码正常工作。我想这里有一个范围问题,但我不明白。为什么在这种情况下update_参数是未定义的,但将它放在window对象中可以让我使用它?(updatepcols是一个更新定价列的函数。)

试试这个。以这种方式使用a将保留对
update\u参数的引用

setTimeout(function(){
    updatepcols(update_argument);
},250);
我有一种有趣的感觉,您作为文本传递的脚本在计算时在全局范围内执行,即在声明
update\u参数的本地范围之外

setTimeout('updatepcols(update_argument)',250);

我不确定这是否是一个范围问题,但更改setTimeout调用应该可以做到:

window.setTimeout('updatepcols('+update_argument+')',250);

这把小提琴表明:

改变你的表情。如果要将局部变量传递给回调函数,则应这样编写:

window.setTimeout('updatepcols('+update_argument+')', 250);
或者,如果要使用闭包,请执行以下操作:

window.setTimeout(function(){ updatepcols(update_argument) }, 250);

是的,正如其他人所说,使用闭包是更好的做法。

这是有效的,因为当您将字符串传递到
setTimeout
时,它在全局范围内是
eval
d。当你传递一个函数时,它可以读取局部变量。最好总是将函数传递给
setTimeout
。永远不要传递字符串。基本上,
setTimeout(codestring,timeout)
的工作方式与
eval
的工作方式相同,这意味着它很慢并且有潜在危险(请参阅)。JavaScript真正的强大之处在于它能够对函数执行任何操作,因此请正确使用它!我所有有组织的培训都是用BASIC和Pascal进行的,我从来没有在这两种语言中使用过闭包。这对我来说是个新概念。我得多读一点。我见过我认为在PHP中被称为“匿名函数”的函数,它们看起来像那样,但也从未使用过。我投了赞成票,因为这是对我问题的直接回答,但我会接受另一个,因为它告诉我们更好的方法。