Javascript 未捕获的 ReferenceError: i 未定义

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/31120478/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-23 06:15:50  来源:igfitidea点击:

Uncaught ReferenceError: i is not defined

javascriptjquery

提问by cyber8200

I'm trying to make a for-loop base on my array

我正在尝试基于我的数组创建一个 for 循环

var lists = [ "a", "b", "c", "d" ];

var lists = [ "a", "b", "c", "d" ];



JS

JS

for ( i = 0; i < lists.length; i++) {

    // console.log(lists[i]);

    $(".sa-report-btn-"+lists[i] ).click(function () {
        $(".sa-hide-"+lists[i]).removeClass("hidden");
        $(".sa-report-"+lists[i]).addClass("hidden");
    });

    $(".sa-hide-btn-"+lists[i]).click(function () {
        $(".sa-hide-"+lists[i]).addClass("hidden");
        $(".sa-report-"+lists[i]).removeClass("hidden");
    });
}

Am I doing it correctly ? I got Uncaught ReferenceError: i is not definedCan I concat each loop with my jQuery selector like this --> $(".sa-hide-"+lists[i])? just curious ...

我做对了吗?我Uncaught ReferenceError: i is not defined可以像这样使用我的 jQuery 选择器连接每个循环 -->$(".sa-hide-"+lists[i])吗?只是好奇 ...

回答by T.J. Crowder

First off, it sounds like you're using strict mode — good! It's saved you from falling prey to The Horror of Implicit Globals.

首先,听起来您正在使用严格模式 -很好!它使您免于成为The Horror of Implicit Globals 的牺牲品。

There are two issues with the code.

代码有两个问题。

The first one is that you're missing the declaration for i. You need to add var i;above the loop, e.g:

第一个是您缺少i. 您需要var i;在循环上方添加,例如:

var i;
for ( i = 0; i < lists.length; i++) {
// ...

or

或者

for (var i = 0; i < lists.length; i++) {

Note, though, that even in that latter example, the ivariable is function-wide, not limited to the forloop.

但是请注意,即使在后一个示例中,i变量也是函数范围的,不限于for循环。

The second one is more subtle, and is outlined in this question and its answers: Your clickhandlers will have an enduring referenceto the ivariable, not a copy of it as of where they were created. So when they run in response to a click, they'll see ias the value lists.length(the value it has when the loop has finished).

第二个更微妙,并在此问题及其答案中进行了概述:您的click处理程序将具有对变量的持久引用i,而不是从创建它们的位置开始的副本。因此,当它们响应单击而运行时,它们将看到ilists.length(循环完成时的值)。

In your case, it's really easy to fix (and you don't have to declare ianymore): Remove the loop entirely, and replace it with Array#forEachor jQuery.each:

在您的情况下,它真的很容易修复(并且您不必再声明i):完全删除循环,并将其替换为Array#forEachor jQuery.each

lists.forEach(function(list) {

    $(".sa-report-btn-" + list).click(function () {
        $(".sa-hide-" + list).removeClass("hidden");
        $(".sa-report-" + list).addClass("hidden");
    });

    $(".sa-hide-btn-" + list).click(function () {
        $(".sa-hide-" + list).addClass("hidden");
        $(".sa-report-" + list).removeClass("hidden");
    });
});

If you need to support really old browsers, you can either shim Array#forEach(which was added in 2009, as part of ECMAScript5), or you can use $.each(jQuery.each) instead:

如果您需要支持非常旧的浏览器,您可以使用 shim Array#forEach(它是在 2009 年添加的,作为 ECMAScript5 的一部分),或者您可以使用$.each( jQuery.each) 代替:

$.each(lists, function(index, list) {
// Note addition ------^
    $(".sa-report-btn-" + list).click(function () {
        $(".sa-hide-" + list).removeClass("hidden");
        $(".sa-report-" + list).addClass("hidden");
    });

    $(".sa-hide-btn-" + list).click(function () {
        $(".sa-hide-" + list).addClass("hidden");
        $(".sa-report-" + list).removeClass("hidden");
    });
});

Note that we don't actually use indexanywhere in our callback, but we have to specify it because $.eachcalls our callback with the index as the first argument, and the value as the second. (Which is why I prefer Array#forEach.) So we have to accept two arguments, with the one we want being the second one.

请注意,我们实际上并没有index在回调中使用任何地方,但我们必须指定它,因为$.each调用我们的回调时将索引作为第一个参数,将值作为第二个参数。(这就是我更喜欢的原因Array#forEach。)所以我们必须接受两个参数,我们想要的一个是第二个。