Javascript 如何修复 jslint 错误“不要在循环中创建函数。”?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/3037598/
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
How to fix jslint error 'Don't make functions within a loop.'?
提问by Ernelli
I am working on making all of our JS code pass through jslint, sometimes with a lot of tweaking with the options to get legacy code pass for now on with the intention to fix it properly later.
我正在努力使我们所有的 JS 代码都通过 jslint,有时需要对选项进行大量调整以获得遗留代码,以便以后正确修复它。
There is one thing that jslint complains about that I do not have a workround for. That is when using constructs like this, we get the error 'Don't make functions within a loop.'
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]);
}
}
This loop is part of a JS implementation of classical inheritance where classes that extend existing classes retain the super property of the extended class when invoking a member of the extended class. Just to clarify, the implementation above is inspired by this blog postby John Resig.
这个循环是经典继承的 JS 实现的一部分,其中扩展现有类的类在调用扩展类的成员时保留扩展类的 super 属性。澄清一下,上述实现的灵感来自John Resig 的这篇博文。
But we also have other instances of functions created within a loop.
但是我们也有在循环中创建的其他函数实例。
The only workaround so far is to exclude these JS files from jslint, but we would like to use jslint for code validation and syntax checking as part of our continuous integration and build workflow.
到目前为止唯一的解决方法是从 jslint 中排除这些 JS 文件,但我们希望使用 jslint 进行代码验证和语法检查,作为我们持续集成和构建工作流的一部分。
Is there a better way to implement functionality like this or is there a way to tweak code like this through jslint?
有没有更好的方法来实现这样的功能,或者有没有办法通过 jslint 调整这样的代码?
回答by Skilldrick
Douglas Crockford has a new idiomatic way of achieving the above - his old technique was to use an inner function to bind the variables, but the new technique uses a function maker. See slide 74 in the slides to his "Function the Ultimate" talk. [This slideshare no longer exists]
Douglas Crockford 有一种新的惯用方式来实现上述目标——他的旧技术是使用内部函数来绑定变量,但新技术使用了函数生成器。请参阅他的“终极功能”演讲幻灯片中的幻灯片 74。[此幻灯片不再存在]
For the lazy, here is the code:
对于懒人,这里是代码:
function make_handler(div_id) {
return function () {
alert(div_id);
};
}
for (i ...) {
div_id = divs[i].id;
divs[i].onclick = make_handler(div_id);
}
回答by Zhami
(I just stumbled on this questions many months after it was posted...)
(我只是在发布几个月后偶然发现了这个问题......)
If you make a function in a loop, an instance of a function is created for each iteration of the loop. Unless the function that is being made is in fact different for each iteration, then use the method of putting the function generator outside the loop -- doing so isn't just Crockery, it lets others who read your code know that this was your intent.
如果您在循环中创建一个函数,则会为循环的每次迭代创建一个函数实例。除非每次迭代生成的函数实际上都不同,否则使用将函数生成器置于循环之外的方法——这样做不仅仅是 Crockery,它让阅读您代码的其他人知道这是您的意图.
If the function is actually the same function being assigned to different values in an iteration (or objects produced in an iteration), then instead you need to assign the function to a named variable, and use that singular instance of the function in assignment within the loop:
如果该函数实际上是在迭代中分配给不同值的同一个函数(或迭代中生成的对象),那么您需要将该函数分配给一个命名变量,并在分配中使用该函数的单个实例环形:
handler = function (div_id) {
return function() { alert(div_id); }
}
for (i ...) {
div_id = divs[i].id;
divs[i].onclick = handler(div_id);
}
Greater commentary/discussion about this was made by others smarter than me when I posed a similar question here on Stack Overflow: JSlint error 'Don't make functions within a loop.' leads to question about Javascript itself
当我在 Stack Overflow 上提出类似问题时,其他比我更聪明的人对此进行了更大的评论/讨论: JSlint 错误“不要在循环中创建函数”。导致关于 Javascript 本身的问题
As for JSLint: Yes, it is dogmatic and idiomatic. That said, it is usually "right" -- I discover that many many people who vocalize negatively about JSLint actually don't understand (the subtleties of) Javascript, which are many and obtuse.
至于JSLint:是的,它是教条和惯用的。也就是说,它通常是“正确的”——我发现许多对 JSLint 持否定态度的人实际上并不理解(微妙的)Javascript,它们很多而且很钝。
回答by lifebalance
Literally, get aroundthe problem by doing the following:
从字面上看,通过执行以下操作来解决问题:
- Create a
.jshintrcfile Add the following line to your
.jshintrcfile{"loopfunc" : true, // tolerate functions being defined in loops }
- 创建
.jshintrc文件 将以下行添加到您的
.jshintrc文件中{"loopfunc" : true, // tolerate functions being defined in loops }
回答by Evan Trimboli
JSLint is only a guide, you don't always have to adhere to the rules. The thing is, you're not creating functions in a loop in the sense that it's referring to. You only create your classes once in your application, not over and over again.
JSLint 只是一个指南,您不必总是遵守规则。问题是,您不是在循环中创建函数,就像它所指的那样。您只在应用程序中创建一次类,而不是一遍又一遍。
回答by jevon
If you are using JQuery, you might want to do something like this in a loop:
如果您正在使用 JQuery,您可能希望在循环中执行以下操作:
for (var i = 0; i < 100; i++) {
$("#button").click(function() {
alert(i);
});
}
To satisfy JSLint, one way to work around this is (in JQuery 1.4.3+) to use the additional handler data argument to .click():
为了满足 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);
}
回答by Matt Eberts
Just move your:
只需移动您的:
(function (name, func) {...})()
(function (name, func) {...})()
block out of the loop and assign it to a variable, like:
阻止循环并将其分配给一个变量,例如:
var makeFn = function(name, func){...};
var makeFn = function(name, func){...};
Then in the loop have:
然后在循环中有:
prototype[prop] = makeFn(...)
prototype[prop] = makeFn(...)

