开发者

How come JQuery doesn't pass JSLint? [duplicate]

开发者_StackOverflow中文版This question already has answers here: Closed 10 years ago.

Possible Duplicate:

What good is JSLint if jQuery fails the validation

http://code.jquery.com/jquery-1.4.4.js

Go to there and paste it in www.jslint.com

Isn't Jquery supposed to be valid....


It's far too much work to comply with it AND be cross-browser compliant. JSLint is useful but its only a generic parser. jQuery has good reasons to throw errors in it.

Sometimes you just need simple dirty hacks to get code working in non-compliant browsers.

let's look at them one by one :

Problem at line 231 character 20: Expected '===' and instead saw '=='.

return num == null ?

Here jQuery uses == on null to check for both undefined and null. Since jQuery is used as an external library it can't guarantee whether the input we pass to functions will be undefined or null. It is safer for it check for both.

Doing num === undefined || num === null to satisfy JSLint is ridiculous.

Problem at line 446 character 29: Expected a conditional expression and instead saw an assignment.

while ( (fn = ready[ i++ ]) ) {

Here JSLint complains about assignment instead of equals check. The reason JSLint throws this error is because its common to type = instead of == by mistake. Assigning in this while loop is done on purpose to make the code neater.

Problem at line 550 character 9: Empty block.

var key; for ( key in obj ) {}
return key === undefined || hasOwn.call( obj, key );

JSLint complains about an empty for block. This here has been done on purpose because we don't want to do anything with key instead we want to enumerate over all the keys and only care about the last one.

Problem at line 554 character 15: Move 'var' declarations to the top of the function.

for ( var name in obj ) {

JSLint insists on having variables declaration at the top of functions. This is a bit silly and can be ignored if you want to. It's a matter of style.

And then the parser crashes. Let me remove some of the code crashing it and see if I can find more complaints.

Problem at line 792 character 42: The '&&' subexpression should be wrapped in parens.

ua.indexOf("compatible") < 0 && rmozilla.exec( ua ) ||

I actually agree with this one (ua.indexO("compatile") < 0) && is better.

Problem at line 872 character 3: Move the invocation into the parens that contain the function.

})();

For closures like:

(function() {
  
})();
//}());

JSLint prefers to see the function invocation in the brackets as a matter of style. I also agree with this one but it really doesn't matter at all.

Problem at line 972 character 13: 'e' is already defined.

} catch(e) {

Parser is complaining about the reuse of variable e In this case we know that e will only be used locally in that catch block so it doesn't matter if we alter it outside the catch block. Here I prefer the readability of re-using the variable name e

Problem at line 1097 character 21: Expected '===' and instead saw '=='.

elem = elem == window ?

Ok, you caught me on this one. I'm stumped as to why jQuery doesn't use === on window

Problem at line 1621 character 24: Expected an assignment or function call and instead saw an expression.

parent.selectedIndex;

// Safari mis-reports the default selected property of an option
// Accessing the parent's selectedIndex property fixes it
if ( name === "selected" && !jQuery.support.optSelected ) {
    var parent = elem.parentNode;
if ( parent ) {
    parent.selectedIndex;
    

Here's one of those cross-browser compliancy bugs that can be fixed but causes bad code

Problem at line 977 character 17: Missing 'break' after 'case'.

case "last":

JSLint says you should always break after your cases. It's perfectly valid to drop through after a case. In most cases you forgot to break but here this is intentional.

Problem at line 1099 character 77: Expected an assignment or function call and instead saw an expression.

Array.prototype.slice.call( document.documentElement.childNodes, 0 )[0].node...

// Perform a simple check to determine if the browser is capable of
// converting a NodeList to an array using builtin methods.
// Also verifies that the returned array holds DOM nodes
// (which is not the case in the Blackberry browser)
try {
    Array.prototype.slice.call( document.documentElement.childNodes, 0 )[0].nodeType;

The source here speaks for itself. It's a weird statement but if accessing it like this throws an error then it can be caught. It's still valid just JSLint tells you "did you really mean to do this?"

Problem at line 2377 character 15: Bad for in variable 'name'.

for ( name in options ) {

Here JSLint complains about the use of name which can conflict with window.name in global scope. It's a "not quite reserved future keyword but still should be avoided". Were in a closure so it's safe.

Problem at line 2486 character 29: Too many errors. (60% scanned).

JSLint's internal stack can't handle it. I'm going to stop now.

I think the point is illustrated.

JSLint has a lot of "Are you sure you want to do this" and we're telling it yes we want to do this. It might look like a mistake but it's not.


The rules that jslint uses are guidelines, not unbreakable rules. There are many reasons you might want to disregard some of them.

There are quite a few detailed considerations of jslint rules out there; many people disagree with it.

Personally, I like it, but use the comments at the top of each JS file to switch on and off various warnings when I know that what I'm doing is appropriate. We then run jslint against all of our JS as part of the CI tests and it catches a few trivial mistakes now and then without generally bothering us.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜