未捕获的ReferenceError:我没有定义

时间:2015-06-29 16:07:46

标签: javascript jquery

我试图在我的阵列上创建一个for循环基地

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

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");
    });
}

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

1 个答案:

答案 0 :(得分:25)

首先,听起来你正在使用严格模式 - !它让你免于陷害The Horror of Implicit Globals

代码存在两个问题。

第一个是你错过了i的声明。您需要在循环上方添加var i;,例如:

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

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

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

第二个更精细,概述in this question and its answers:您的click处理程序将{em}持久引用到i变量,而不是副本它们的创建地点。因此,当他们针对点击运行时,他们会看到i为值lists.length(循环结束时的值)。

在您的情况下,它很容易修复(您不必再声明i):完全删除循环,并将其替换为Array#forEachjQuery.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");
    });
});

如果您需要支持真正的旧版浏览器,可以使用Array#forEach(在2009年添加,作为ECMAScript5的一部分),或者您可以使用$.eachjQuery.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");
    });
});

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