tags:

views:

119

answers:

6

I'm working with some JS code that I inherited on a project, and in several instances it has loops set up like this one:

while(text = someBufferObject.read()) {
  //do stuff with text
}

I'm assuming this is to achieve some sort of do-while type functionality. However, when I run this through JSLINT it complains that it "Expected a conditional expression and instead saw an assignment."

Is there a more accepted approach that I should use for these loops? I'm not sure if something like below is the best way or not:

text = someBufferObject.read()
while(text) {
  //do stuff with text
  text = someBufferObject.read()
}
+2  A: 

I can only imagine that's a problem with JSLINT, that's completely valid javascript, it's a lot better than the second solution anyway.

Jeffrey Aylesworth
+2  A: 

See if JSLINT complains about this:

while (NULL != (text = someBufferObject.read())) {
  //do stuff with text
}
wallyk
wow, that's much worse than the original. Obfuscating code to satisfy a lint? weak
bobince
I agree it's worse, but not that it is much worse. Certainly the other alternatives are "much worse."
wallyk
+1 for making me laugh at the obfuscation. Depending on the options you set, LINT does/does not complain because you used != instead of !==
dtjohnso
Back in the dark ages of C compilers (c. 1985), I used some braindead compiler which essentially forced the construct above. Otherwise a compile would be a deluge of useless warnings.
wallyk
+1  A: 

Neither example is a "do-while", they're just different code styles that essentially do the same thing. JSLint is simply informing you that the first style goes against best practices.

GalacticCowboy
Any suggestions how I can conform to best practices? I'm happy with it as it is in the first example, but I'm curious what would be considered "best practice" :)
dtjohnso
It's like OtherMichael said, it's a "code smell" - a style that, while syntactically valid, can be the source of bugs if you're not careful. In general, the best practice would be that your loop control should only *test*, not *assign*.With that said, 95% of programmers would do it the first way anyway; it's not an *error* to ignore JSLint - the tool is just there to bring it to your attention but you don't have to follow their advice 100% of the time.
GalacticCowboy
You might even be able to tell JSLint to ignore this rule. But like it says on the JSLint site, "Warning: JSLint will hurt your feelings."
GalacticCowboy
+3  A: 

Is there a more accepted approach

Don't take JSLint's advice as gospel. It is dogmatic opinion from a cranky old man; some of it entirely sensible, some of it rather questionable.

while (variable= assignment), though it might sometimes be a mistaken comparator, is also a widely-understood idiom of C-like languages. Whether you use that approach or another is a matter of taste, something you should weigh up personally rather than blindly accept Crockford's edict.

JavaScript does have a do-while loop, so if your test is consistently at the end that would be a more appropriate construct:

do {
    text= someBufferObject.read();
    // do something
} while (text);

More commonly though what you're looking at is a mid-test loop. You may or may not prefer the break idiom as used by Python:

while (true) {
    text= someBufferObject.read();
    if (!text)
        break;
    // do something
}
bobince
Thanks! I should have remembered the true JS do-while. I'll have to look again at the specific cases in my code and decide my semantic prefs pragmatically.
dtjohnso
+2  A: 

You only need to wrap it in another set of parentheses to make JSLint happy.

while((text = someBufferObject.read())) {
  //do stuff with text
}
Steven Huwig
that's pretty sneaky. I'd probably want to comment the need for double-quotes; if the build requires JSLint no-errors (at a particular) level, f'r instance, I can see why this would have to stay in the code.
Michael Paulukonis
This is actually mentioned by the JSLint author as the way to work around it. http://oreilly.com/javascript/excerpts/javascript-good-parts/jslint.html"If you really intend an assignment, wrap it in another set of parentheses"
Steven Huwig
+1  A: 

JSLint is complaining because it's a JavaScript code-smell -- using a single-equals (assignment operator) instead of double- or tripe-equals (equality/identity operator) is a common mistake.

If your code works, don't sweat the warning. It's an automated tool, not an omniscient tool.

Michael Paulukonis