我正在努力使我们的所有JS代码都通过jslint传递,有时需要进行大量的调整以获得遗留代码的选项,以便稍后正确修复它。
有一件事jslint抱怨说我没有工作。也就是说,当使用这样的结构时,我们会收到错误“不要在循环中创建函数”。
for (prop in newObject) {
// Check if we're overwriting an existing function
if (typeof newObject[prop] === "function" && typeof _super[prop] === "function" &&
fnTest.test(newObject[prop])) {
prototype[prop] = (function(name, func) {
return function() {
var result, old_super;
old_super = this._super;
this._super = _super[name];
result = func.apply(this, arguments);
this._super = old_super;
return result;
};
})(prop, newObject[prop]);
}
}
此循环是经典继承的JS实现的一部分,其中扩展现有类的类在调用扩展类的成员时保留扩展类的超级属性。 只是为了澄清,上面的实现受到了John Resig的blog post的启发。
但我们还在循环中创建了其他函数实例。
到目前为止,唯一的解决方法是从jslint中排除这些JS文件,但我们希望使用jslint进行代码验证和语法检查,作为我们持续集成和构建工作流程的一部分。
有没有更好的方法来实现这样的功能,还是有办法通过jslint调整这样的代码?
答案 0 :(得分:65)
对于懒惰,这是代码:
function make_handler(div_id) {
return function () {
alert(div_id);
};
}
for (i ...) {
div_id = divs[i].id;
divs[i].onclick = make_handler(div_id);
}
答案 1 :(得分:12)
(我发布这个问题几个月后我偶然发现了这个问题......)
如果在循环中创建函数,则会为循环的每次迭代创建函数的实例。除非正在进行的函数实际上对于每次迭代都是不同的,否则使用将函数生成器放在循环之外的方法 - 这样做不仅仅是Crockery,它让其他阅读代码的人都知道这是你的意图
如果函数实际上是在迭代中(或迭代中生成的对象)将相同的函数分配给不同的值,那么您需要将该函数分配给命名变量,并使用该函数的单个实例。循环中的赋值:
handler = function (div_id) {
return function() { alert(div_id); }
}
for (i ...) {
div_id = divs[i].id;
divs[i].onclick = handler(div_id);
}
当我在Stack Overflow上提出类似的问题时,其他人比我更聪明,对此进行了更多的评论/讨论: JSlint error 'Don't make functions within a loop.' leads to question about Javascript itself
至于JSLint: 是的,这是教条和惯用语。也就是说,它通常是“正确的” - 我发现许多对JSLint负面发声的人实际上并不理解(微妙的)Javascript,这很多很麻烦。
答案 2 :(得分:10)
从字面上看,通过执行以下操作来解决问题:
.jshintrc
文件将以下行添加到.jshintrc
文件
{"loopfunc" : true, // tolerate functions being defined in loops }
答案 3 :(得分:7)
JSLint只是一个指南,您并不总是必须遵守规则。问题是,你不是在它所指的意义上在循环中创建函数。您只需在应用程序中创建一次类,而不是一遍又一遍。
答案 4 :(得分:5)
如果您正在使用JQuery,您可能希望在循环中执行类似的操作:
for (var i = 0; i < 100; i++) {
$("#button").click(function() {
alert(i);
});
}
为了满足JSLint,解决此问题的一种方法是(在JQuery 1.4.3+中)使用.click()
的附加处理程序数据参数:
function new_function(e) {
var data = e.data; // from handler
alert(data); // do whatever
}
for (var i = 0; i < 100; i++) {
$("#button").click(i, new_function);
}
答案 5 :(得分:3)
移动你的:
(function (name, func) {...})()
阻止循环并将其分配给变量,例如:
var makeFn = function(name, func){...};
然后在循环中有:
prototype[prop] = makeFn(...)