views:

336

answers:

3

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.

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.'

        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 post by 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.

Is there a better way to implement functionality like this or is there a way to tweak code like this through jslint?

A: 

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.

Evan Trimboli
I know that jslint is only a recomendation and that it's intended to be used to spot bad JS code, but it's still a good tool to use to pre-qualify and sanity check your code in an automated build/test environment.As I wrote, I'm interested in workarounds to make the code pass jslint, not avoid running jslint at all.
Ernelli
Sure, but if you look at the answer below, you're still making a function in a loop. You're adding extra code just to appease JSLint. Why would you do this?
Evan Trimboli
Yes I still make functions within a loop, my problem was that I wanted this code to pass jslint. Now Skilldrick and Matt Eberts gave me working solutions which I have tested and now my code both works and passes jslint. I am an old C/C++ programmer, I'm used to have syntax checking as part of the compilation stage. Javascript lacks compilation, jslint is as close as you get to using a modern c/c++ compiler with warnings.
Ernelli
Of course, those solutions are obvious. The point remains, you're still creating functions inside the loop, you've just written it in a particular way that is arguably more convoluted, just to appease some tool. Whatever, if that's what you want to do, go for it.
Evan Trimboli
+1  A: 

Just move your (function (name, func) {...})() block out of the loop and assign it to a variable, like:

var makeFn = function(name, func){...};

Then in the loop have:

prototype[prop] = makeFn(...)

Matt Eberts
+5  A: 

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.

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