Javascript 为什么我的计数器每次添加一个以上?

Javascript 为什么我的计数器每次添加一个以上?,javascript,jquery,Javascript,Jquery,我正在使用jQuery创建一个测试,但不知道为什么在使用正确答案时,我的计数器变量“count”似乎增加了不止一个 function nextQuestion(){ $('#submit').show(); $('#next').hide(); $('#result').text(''); $('#value').val(''); randomNumber = Math.floor((Math.random() * words.length));

我正在使用jQuery创建一个测试,但不知道为什么在使用正确答案时,我的计数器变量“
count
”似乎增加了不止一个

function nextQuestion(){
    $('#submit').show();
    $('#next').hide();
    $('#result').text('');
    $('#value').val('');
    randomNumber = Math.floor((Math.random() * words.length));
    $('#englishWord').text(words[randomNumber][0]);
    $('#submit').click(function(){
        if ($('#value').val() == words[randomNumber][1])
        {
            $('#result').text("You are correct, well done");
            $('#submit').hide();
            $('#next').show();

            $('#next').click(function(){
                count = count + 1;
                $('#score').text(count); 
                nextQuestion();              
            });
        }
        else 
        {
            $('#result').text("That is incorrect, try again");
            count = 0;
            $('#score').text(count);
        }
    });
}

每次单击
#next
时,
计数将增加一个以上,因为您正在向
#next
元素的
单击事件添加多个匿名侦听器。每个函数都独立地将
1
添加到
count
。因此,当单击
#next
时,对于添加到
#next
元素上的
click
事件中的每个匿名侦听器,
计数将增加1

每次点击
#submit
$(“#value”).val()==words[randomNumber][1]
时,您执行:

$('#next').click(function(){
    count = count + 1;
    $('#score').text(count); 
    nextQuestion();              
});
这将导致一个新的匿名函数作为侦听器添加到
#next
元素的
click
事件中,以及任何已经侦听该事件的函数。因此,每次在
#next
上出现
单击事件时,都会调用多个函数,每个函数将
计数增加1。每次点击
#next
的总增加量取决于您收听该事件的功能数量

对于
#submit
元素的
单击事件,您也有同样的问题。这会通过向
#next
元素的
单击事件添加更多侦听器,导致
计数进一步增加。第一次单击
#submit
时,会添加一个侦听器。在第二个
#submit
事件中,单击两个侦听器到
#submit
单击
事件,每个侦听器向
#下一个
单击
事件添加另一个侦听器,使该事件总共有3个侦听器。因此,
count
增加3。当您向每个事件添加越来越多的侦听器时,这将继续扩展

让代码只添加一次事件侦听器 解决方案是只分配这些单击事件一次:

$('#submit').click(function(){
    if ($('#value').val() == words[randomNumber][1])
    {
        $('#result').text("You are correct, well done");
        $('#submit').hide();
        $('#next').show();
    }
    else 
    {
        $('#result').text("That is incorrect, try again");
        count = 0;
        $('#score').text(count);
    }
});

$('#next').click(function(){
    count = count + 1;
    $('#score').text(count); 
    nextQuestion();              
});

function nextQuestion(){
     $('#submit').show();
     $('#next').hide();
     $('#result').text('');
     $('#value').val('');
     randomNumber = Math.floor((Math.random() * words.length));
     $('#englishWord').text(words[randomNumber][0]);
}
或者,使用命名函数并依赖以忽略添加相同侦听器的尝试。 另一种解决方案是使用单个命名函数,该函数在一个作用域中定义,这样就不会在每次调用添加它的代码时重新定义它。未使用添加的侦听器(例如,
)是使用添加的(jQuery在为添加事件侦听器提供的各种方法中使用此方法)。如果尝试将相同的函数添加到
addEventListener()
,并对其他参数使用相同的值,则。这意味着,即使尝试使用相同的参数多次添加相同的函数,每个事件也只能调用一次。对于匿名函数,每次运行代码时都会单独定义该函数。因此,虽然代码是相同的,但所定义的函数与代码运行之前的任何时间都是分离的。因此,会添加多个副本


然而,仅仅因为函数有一个名称并不意味着它是在一个作用域中定义的,这将导致每次添加它时不会重新定义它。例如,在上面的代码中,如果
#next
侦听器的函数是在
#submit
侦听器中定义的,并且即使它有一个名称,每次运行
#submit
侦听器时都会重新定义它。为了防止函数被重新定义,关键是如何以及在何处定义函数,而不仅仅是它是一个命名函数。但是,为了引用该函数,它必须有一个名称,或者与一个变量相关联。因此,您通常会发现,当有人说“命名函数”时,有一种假设,即它的定义方式通常不会重新定义。

计数器是多少,count?tha Math.random()生成介于0和1之间的数字,我不明白你是怎么用它作为随机数的。如果计数器变量是count,你应该给出你问题的一个工作示例……这只是代码的一部分,随机生成器会生成一个介于1和“单词”数组长度之间的数字。错误提示:下次遇到这种情况时,在似乎无法正常工作的行前面放置一个警报`count=count+1;`,在这种情况下,您会看到它在第一次单击时执行一次,在第二次单击时执行两次,甚至更多。这可能足以让你自己找到答案。这基本上是正确的。但是命名函数不会有帮助——至少,如果函数是在
“#submit”处理程序中定义的,那么命名函数不会有帮助。你也会遇到同样的问题。如果使用在外部作用域中定义的命名函数,则两个
$('#next')。单击
调用将使用相同的处理程序,而不是碰巧执行相同操作的不同处理程序。但我怀疑这会有帮助——我不相信它会检查函数的相等性。如果它确实起作用,那么重要的一点不是函数是否命名,而是在何处声明。在js中,函数是否命名并不重要。@DavidKnipe,您是正确的。我在写这篇文章时,假设命名函数的定义方式和范围都不明确,因此每次调用任何一个事件处理程序时都不会重新定义它。我已经重写了。但是,确实如此。