为什么我不能在javascript中传递值?

时间:2011-11-18 13:04:50

标签: javascript variables

for (id = 50; id < 100; id++)
{
    if($('#'+id).attr('class') == 'myField')  
    {
            $('#'+id).bind('click', function() { install(id); } );
    }
}

不知道为什么id无法在function()中达到'install'。我试图用click事件绑定每个按钮(id为50到100)以触发install(id)函数。但似乎变量id无法达到安装功能。虽然我硬编码:

for (id = 50; id < 100; id++)
{
      if($('#'+id).attr('class') == 'myField')  
      {
            $('#'+id).bind('click', function() { install( 56 ); });
      }
}

它有效!请告诉我原因。

5 个答案:

答案 0 :(得分:4)

你所做的是使用Javascript闭包时最常见的错误之一。

顺便说一句,这个错误如此常见的事实是IMO证明它确实是语言本身的“错误”。

Javascript支持读写闭包,因此当您在闭包中捕获变量时,它不是捕获的变量的当前,而是变量本身。 这意味着例如在

var arr = [];
for (var i=0; i<10; i++)
    arr.push(function(){alert(i);});

数组中的10个函数中的每一个都将包含一个闭包,但它们都将引用循环中使用的相同i变量,而不是该变量在闭包时所具有的值。创建。因此,如果您调用它们中的任何一个,则输出将是相同的(例如,如果您在循环之后立即调用它们,则为10。)

幸运的是,解决方法很简单:

var arr = [];
for (var i=0; i<10; i++)
    arr.push((function(i) {
                return (function(){alert(i);});
              })(i));

使用这个“包装”你正在调用一个匿名函数,在该函数中,变量i与循环不同,实际上是每个调用的不同变量。在函数i内部只是一个参数,返回的闭包绑定到该参数。

在您的情况下,解决方案是:

for (id = 50; id < 100; id++)
{
    if($('#'+id).attr('class') == 'myField')  
    {
        $('#'+id).bind('click',
           (function(id){
                 return (function() { install(id); });
            })(id));
    }
}

答案 1 :(得分:3)

未达到install() ,我想你的意思是说你的所有install(id)行为都像install(100)

无效的原因

这是由javaSctipt闭包引起的。此行function() { install(id) }id分配给install()回调函数。在id被调用之后,install()的值将在循环结束后很晚才会被解析 - id已经达到100的时间。

解决方案是创建另一个闭包,保持当前id值。

for (id = 50; id < 100; id++)
{
    if($('#'+id).attr('class') == 'myField')
    {
            (function (id) {
              $('#'+id).bind('click', function() { install(id); });
            }) (id);

    }
}

这是一个演示代码:

var funcCollections = [];
for (id = 50; id < 100; id++)
{
    if(true)
    {
            (function () {
              var thatId = id;
              funcCollections.push(function () {console.log(thatId,id)});
            }) ();

    }
}

// funcCollections[1]();
// 51 100
// undefined
// funcCollections[2]();
// 52 100

答案 2 :(得分:1)

您无法将变量传递给您绑定的函数。它失去了val。当你传递'56'时它总是56,但是当你传递一个var时,JavaScript不会绑定循环中var的值。

答案 3 :(得分:1)

当你遍历变量并创建引用循环变量的匿名函数(闭包)时,它们将引用最后一个值

另请注意,您不必将循环变量的范围限制为for循环(它未使用var声明),这意味着稍后对该变量的修改将传播到所有闭包。

看看this

答案 4 :(得分:1)

归结为variable scope

您绑定到$('#' + id)元素的click事件的匿名函数无法识别示例代码中的id变量(假设您的示例代码是函数的摘录) )。即使它确实如此(例如你在任何函数之外声明id,给它全局范围),id将在调用click事件时保持值 100 ,这不是不是你想要的。

但是,您可以使用$(this).attr('id')来获取元素的id值:

for (id = 50; id < 100; id++)
{
    if($('#' + id).attr('class') == 'myField')  
    {
        $('#' + id).bind('click', function()
        {
            install(parseInt($(this).attr('id')));
        });
    }
}

查看jQuery .bind()文档,其中显示了如何在事件处理程序中使用this