jslint - 不要在循环中创建函数

时间:2013-03-27 17:02:02

标签: javascript jslint

参考此主题:Don't make functions within a loop. - jslint error

你如何在for循环中处理jquery .each(function(){...}?知道我需要在“each”函数中使用“for”的上下文。当然我可以将每个所需的映射到函数的参数是在循环外声明的函数,但从我的角度来看,它会影响可读性。

有什么想法吗?

提前致谢。

3 个答案:

答案 0 :(得分:9)

好吧,你可以在你的循环中保留for的上下文,因为for中的所有内容实际上都与在开始时声明的函数在同一个上下文中。

所以让我们以Frits的例子为例,但首先让我们首先让JSLint完全满意(减去循环错误中调用的函数)。

/*global console*/
var my_func, i, list;
for (i = 0; i < list.length; i+= 1) {
    my_func = function (i) {
        console.log(i);
    };
    my_func(i);
}

请注意每次迭代循环时,您重新声明 my_func函数。那不酷!为什么一遍又一遍地重新声明相同的功能?

早先声明它,如下:

/*global console*/
var my_func, i, list;

my_func = function (i) {
    console.log(i);
};

for (i = 0; i < list.length; i+= 1) {
    my_func(i);
}

成功。现在,您不需要为每次迭代创建一个函数。而且,由于JSLint通过将所有var声明推送到顶部来帮助您实现,您仍然可以获得相同的上下文。


编辑:作为@Flame points out,您不必使用jQuery each尽早声明该函数,并且可以使用匿名函数,但这不是一个坏主意尽早声明,特别是如果您要在多个each调用中重用逻辑。主要的理解是1.)早期的声明实践仍然有优势,2)jQuery仍然会发送你的函数的参数(这里,我们称之为index),虽然JSLint将(并且不应该)抱怨each s(jQuery sauce here)中使用的匿名函数。

如果你已经习惯了匿名的$.each(function() {});结构,那么它最初会变得更不直观。但它也很简单。

/*global alert, $ */
$( "li" ).each(function( index ) {
    alert( index + ": " + $(this).text() );
});

......变成......

/*global $, alert */
var fnOutside = function(index) {
    alert( index + ": " + $(this).text() );
};
$( "li" ).each(fnOutside);

这可能会让人感到困惑,因为函数调用没有参数,但是jQuery正在将“index”参数推送到函数中。您可以抓住上下文arguments数组,看看它是否仍然被推入那里,如果您想要保留命名。

Fiddle-ige

也就是说,for构造不会创建新的闭包。这可能让你担心。没问题!

答案 1 :(得分:4)

循环中函数的问题是:this,

for (var i = 0; i < list.length; i+= 1) {
    function my_func(i) {
        console.log(i);
    }
    my_func(i);
}

将被解释为:

var my_func;
for (var i = 0; i < list.length; i+= 1) {
    my_func = function (i) {
        console.log(i);
    }
    my_func(i);
}

由于可变吊装。所有声明都将移动到范围的顶部(即函数)。因此,在for循环中定义函数实际上没有意义。

如果要在for循环中绑定到计数器,只需创建一个闭包。

要明确:

$("..").each(function () {
    for(..) {
    }
});

很好。

for(..) {
    $("..").each(function () {

    });
}

不好,因为它等同于:

var my_func;
for(..) {
    my_func = function () {
        // ..
    }
    $("..").each(my_func);
}

答案 2 :(得分:2)

听起来问题更多的是警告而不是代码。是的,在没有警告的情况下传递JSLint测试会很好,但是其中一些可能是不合理的并导致不必要的代码重构。

本Q&amp; A中的讨论是相关的:Should I use JSLint or JSHint JavaScript validation?其他lint工具比JSLint具有更大的灵活性,因此您可以继续提高个人编码偏好,而不一定是Crockford的个人编码偏好。

我建议您考虑使用其他工具来填充您的JavaScript,并且不要牺牲代码的可读性或可维护性。