The JavaScript Code Quality Tool
See all
Members (730)
Douglas Crockford's profile photo
Madara Uchiha's profile photo
Myoung-ho Choi's profile photo
Ryan McQuen's profile photo
Ahmed Abdalla's profile photo
Gaurav Mishra's profile photo
Darrell Little's profile photo
Denis Bešić's profile photo
Karol L's profile photo
Михаил Шестаков's profile photo
Oliver Guether's profile photo
WebmasterUM Guilherme's profile photo
Paul Wilkins's profile photo
Christopher Karl Johansen (Xojo)'s profile photo
Ben Quarmby's profile photo
N Shathish's profile photo
Maulik Gangani's profile photo
William Malone's profile photo
psp i's profile photo
Harish Ramarao's profile photo
Rob Hughes's profile photo
Eugenio Gonzato's profile photo
Paul Crowder's profile photo
Bhavik Makwana's profile photo

Stream

Ben Quarmby

Discussion  - 
 
JSLint warns on the redefinition of "name" in this fabricated example.

| /jslint node/
| "use strict";
|
| var name = "outer";
|
| function method() {
| var name = "inner";
|
| return name;
| }
|
| module.exports = {
| name: name,
| method: method
| };

But not in this example. Should it?

| /jslint node/
| "use strict";
|
| function method() {
| var name = "inner";
|
| return name;
| }
|
| var name = "outer";
|
| module.exports = {
| name: name,
| method: method
| };
1
Fedge No's profile photo
 
I think this is acceptable because there's no way the inner "name" can be accessed in the outer scope by the time the second var statement is reached. In the example that fails, "name" is already accessible in the inner scope even if you don't define it, which could cause a JS engine to overwrite it without warning you if you assigned a value to it and forgot to use a var statement.
Add a comment...

Rutger Meekers

Discussion  - 
 
I get a few warnings on this codeblock:

getApiData: function(account, property, index, cb) {
try {
var result = Analytics.Management.CustomDimensions.get(account, property, index);
}
catch (e) {
var result = e; //W004 - 'result' is already defined
}

if (typeof cb === 'function') {
return cb.call(this, result); //W038 - 'result' used out of scope
}
else {
return result; //W038 - 'result' used out of scope
}
}

What's wrong here?

1
Douglas Crockford's profile photoRutger Meekers's profile photo
6 comments
 
Ah indeed. Sorry, missed that part from your examples. Thanks a lot +Douglas Crockford and +Brian Kieffer
Add a comment...

Tom Brodhead

Discussion  - 
 
I'm unclear how to interpret this warning as well as how to eliminate it:

Unexpected 'while' at top level.

I can't find anything on the help page that addresses this.
1
Douglas Crockford's profile photoTom Brodhead's profile photo
3 comments
 
+Douglas Crockford Could you add to the warning message "Move it to a function" or similar language? Also, the help section of JSLint site doesn't seem to explain "top level" code and how it should be treated specially...perhaps a brief clarification of that would be helpful. Many thanks!
Add a comment...

Tom Brodhead

Discussion  - 
 
Does JSLint tolerate any use of 'this' aside the user checking Tolerate... [x] 'this'? If so, in what circumstances?
1
Fedge No's profile photoTom Brodhead's profile photo
8 comments
 
Thanks for that, and I just discovered that even the harmless-looking extension to the Array prototype that I provided above (for returning a random value from an array) causes strange behavior. When initializing an empty, multi-dimensional array, unintended values are added to the higher dimensions when that prototype extension is active. So...perhaps JSLint should issue a warning when a built-in object prototype is extended? Warning the user to avoid 'this' doesn't cover that scenario; 'this' is an operator that would be found in a declaration of such an extension, but a simple warning not to extend the built-in object prototypes is a different category of advice, and I believe it would be helpful. (A simple, one-sentence explanation in the help section of JSLint would suffice; users could then Google to find longer discussions, etc.)
Add a comment...

Tom Brodhead

Discussion  - 
 
I believe the documentation on the white space requirements for ternary operators could be improved with an example. The current description:

"The ternary operator can be visually confusing, so ? question mark and : colon always begin a line and increase the indentation by 4 spaces."

...was ambiguous to me. It could be illustrated clearly with:

var x = Math.PI > 4
? "Yep"
: "Nope";

...or similar, which I only obtained by trial and error. (I placed 4 white spaces before the 2nd and 3rd lines above, but this editor will likely strip them out when I submit this post.)
1
Douglas Crockford's profile photo
 
Thanks.
Add a comment...

Tom Brodhead

Discussion  - 
 
I'm trying to eliminate 'this' in some JQuery code. The code makes use of the $(selector).each() function, documented here:

https://api.jquery.com/each/

Although the documentation provides an example of a way to use an equivalent function that does not use 'this', the first example they provide requires 'this' and is a thorn to JSLint:

$("li").each(function(index) {
console.log(index + ": " + $(this).text());
});

My code is a bit more complex, but if there's a way to avoid using 'this' while using .each() (instead of abandoning it for a different operator), it would be preferable. The relevant lines from a sample code block I'm trying to edit are:

$("#edit_keyword_form :checkbox").not("#new_keyword :checkbox").each(function () {
$(this).on("click", function () {
if ($(this).is(":checked")) {
var li = $(this).parent("li");
// more code follows
}
});
});
jQuery: The Write Less, Do More, JavaScript Library
1
raal Bvv's profile photo
 
Should be possible without this:

$("#edit_keyword_form :checkbox").not("#new_keyword :checkbox").each(
function (unusedIndex, element) {
$(element).on("click", function (event) {
var jQueryTarget = $(event.target);
if (jQueryTarget.is(":checked")) {
var li = jQueryTarget.parent("li");
// more code follows
}
});
});

Add a comment...

Tom Brodhead

Discussion  - 
 
This code:

var x = new RegExp(find.replace(/[-\/\\^$*+?.()|[\]{}]/g, "\\$&"), "g");

Produces this JSLint "unable to finish" response:

Expected ']' and instead saw '-'.

...at character position 36

How do I alter the regex (which is valid and apparently well-formed) to allow JSLint to finish?
1
Douglas Crockford's profile photoTom Brodhead's profile photo
14 comments
 
Many thanks!
Add a comment...

Tom Brodhead

Discussion  - 
 
JSLint fails to recognize functions that begin with a capital letter. For example:

"use strict";
var console;
function X(text) {
console.log(text);
}
X("Hello");

...throws the warning "Expected 'new' before 'X'" in reference to X("Hello");

On the other hand, if the function does not begin with a capital letter, it issues no such warning. Is there a convention to avoid capitalizing function names in deference to a different JavaScript type (here, presumably an object) that typically is capitalized?
1
Tom Brodhead's profile photoStéphane Trebel's profile photo
3 comments
 
It's mentionned in http://www.jslint.com/help.html ("Constructors and new" section) if you want to have a little more insight on this
Add a comment...
 

Proposal: Every function should have zero or one parameter.
Multiple arguments can be passed by wrapping them in an object.
This restriction will make programs more extensible and easier to read.
old way: draw_rect(0, 0, 50, 50)
new way: draw_rect({ x: 0, y: 0, width: 50, height: 50 })
In my opninion the old way is almost as cryptic as assembly language.
4
Fedge No's profile photoΝίκος Καλογρίδης's profile photo
5 comments
 
+Fedge No​ you are always in development mode in software 😃
Add a comment...
 
Should JSLint favor

const foo = function foo(...) {
...
};

over

function foo(...) {
...
}

when es6 is enabled? The former will throw a TypeError if foo is reassigned. JSLint already warns when a function name is reassigned and if is used before is declared.
1
Nicola Squartini's profile photo
3 comments
 
I mentioned that JSLint already warns when a function name is reassigned; the "const" form would also cover the case when the function is exported and reassigned in the importer module.
Add a comment...

Chris Rowett

Discussion  - 
 
This works:
var a = "a", b = a.charCodeAt(0);

But this reports a problem:
var c = "a".charCodeAt(0);

Unexpected '.'.

Why?
1
Brian Kieffer's profile photoNicola Fankhauser's profile photo
3 comments
 
See the discussion in this thread where interestingly this behavior was described as intentional: https://plus.google.com/116155444999910002488/posts/EdhyU8tYn1Y

Add a comment...

About this community

This group is for discussion of JSLint, including feature requests, complaints, update announcements, and testimonials.

Tom Brodhead

Discussion  - 
 
JSLint fails to catch this apparent error:

var myArray = [1, 2, 3];
var my_unrelated_variable = "fish";
myArray.pop(my_unrelated_variable);

pop() receives no arguments, right?
1
chris l's profile photoTom Brodhead's profile photo
4 comments
 
Point well taken. It's frustrating that there's no IDE for JS outside of the auxiliary tools we've already discussed.
Add a comment...

Tom Brodhead

Discussion  - 
 
Because JSLint can, in some cases, read more than the syntax of JavaScript (e.g., suggesting breaking up 'if-else' structures when the else only contains a 'return'), I'm uncertain if it's within the trajectory of its intentions that it should trigger a warning message for the following scenario:

var num_str = "0123456789";
var digit = 3;
var index = num_str.indexOf(digit);

This passes JSLint, and even the "simple" option of the online Google closure compiler (https://closure-compiler.appspot.com/home). However, when the "advanced" option of that compiler is selected, it catches the error of passing a numeric into the indexOf() on a string with this message:

JSC_TYPE_MISMATCH: actual parameter 1 of String.prototype.indexOf does not match formal parameter
found : number
required: (null|string) at line 3 character 28
var index = num_str.indexOf(digit);
^
This may be beyond the scope/ability of JSLint, but I thought I'd mention it.
Example: http://www.example.com/bigfile.js. Optimization: Whitespace only. Simple Advanced. Which optimization is right for my code? Formatting: Pretty print. Print input delimiter. Compile. Reset. // ==ClosureCompiler== // @compilation_level SIMPLE_OPTIMIZATIONS // @output_file_name default.js ...
1
Stéphane Trebel's profile photoJames Long's profile photo
4 comments
 
The bigger problem with the proposal is that JavaScript is designed to be loosely typed. Everything inherits from Object.prototype, Object.prototype has a toString method so every variable can be used as a string (which can be parsed as a number for situations where numbers are required). Consider these examples:

"a".concat();
// -> "a"
"a".concat("b");
// -> "ab"
"a".concat(1);
// -> "a1"
"a".concat(true)
// -> "atrue"
"a".concat([1, 2]);
// -> "a1,2"
"a".concat(/\s+/);
// -> "a/\s+/"
"a".concat(undefined)
// -> "aundefined"
"a".concat(null)
// -> "anull"
"a".concat(function () { return; });
// -> "afunction () { return; }"
"a".concat({a: 1});
// -> "a[object Object]"
"a".concat({toString: function () { return "b"; }});
// -> "ab"

There's no SyntaxError because in every case, toString() is called and the result is concatenated onto the original string. There are precious few reasons why you'd want to pass something other than a string to concat(), but JavaScript is designed to handle those situations. There is no error so there is no need for JSLint to pick up on them (or for Google Closure Compiler's Advanced mode).
Add a comment...

Brian Kieffer

Discussion  - 
 
A proposal: I think JSLint should enforce writing JSON objects with one property per line. For example, the following should throw the warnings:

Expected 'bar' at column 4, not column 11
Expected 'baz' at column 4, not column 19
Expected '}' at column 0, not column 25
Expected ';' at column 1, not column 26.


var foo = {bar: 1, baz: 2};
1
Nathan Ho's profile photoBrian Kieffer's profile photo
6 comments
 
+Nathan Ho It helps with readability. IMO, this would help more than the enforced formatting of the ternary operator.
Add a comment...

Mathias Nater

Discussion  - 
 
JSLint expects ';' after export default function (…) { … }, but shouldn't:

/jslint es6/
export default function () {
return undefined;
}

->Expected ';' and instead saw '(end)'.

http://www.ecma-international.org/ecma-262/6.0/#sec-exports

https://developer.mozilla.org/en/docs/web/javascript/reference/statements/export
1
Nicola Squartini's profile photo
6 comments
 
Ops. I just followed the misleading chain of links, which starts with AssignmentExpression -> ConditionalExpression -> ... and ends pointing to the wrong definition of http://www.ecma-international.org/ecma-262/7.0/#prod-UpdateExpression
Add a comment...

raal Bvv

Discussion  - 
 
Is there any plan to add another environment to JSLint ? we already have browser, which defines XMLHttpRequest, document and more as globals, we already have node that defines require Buffer etc. Now it would be cool to have the worker mode , for web workers , service workers and shared workers, . Also worker don't have DOM access, and are isolated, so there is no need to wrap it in an IIFE, , right now workers passed to JSLint get Unexpected 'use strict'. error, which is kinda wrong see https://developer.mozilla.org/en-US/docs/Web/API/Web_Workers_API/Using_web_workers
A worker is an object created using a constructor (e.g. Worker()) that runs a named JavaScript file — this file contains the code that will run in the worker thread; workers run in another global context that is different from the current window. Thus, using the window shortcut to get the current global scope (instead of self) within a Worker will return an error.
1
Douglas Crockford's profile photoraal Bvv's profile photo
2 comments
 
I am still figuring out best practices with web workers, when I have more experience I'll tell.
Add a comment...

Doug Kunzman

Discussion  - 
 
I have a question about arrow functions. Our code looks like this...
router.get('/hello', (req, res) => {
res.json({
message: 'Hello Test'
});
});
and JSLint is returning the following warning "Expected 'function' and instead saw '=>'." Does JSLint ever accept arrow functions when es6 is enabled? If not why are arrow functions universally bad? I'm running JSLint from github inside a tomcat container that was pulled yesterday.
1
Douglas Crockford's profile photoLee Chase's profile photo
2 comments
 
Arrow functions have a problem with { }, mainly is it a multiline function or an object.

As it happens your function returns nothing as multiline arrow functions need a return. You could write as

router.get('/hello', (req, res) => res.json({message: 'Hello Test'}));

Linter may still object.
Add a comment...

Doug Kunzman

Discussion  - 
 
JSLint is giving me the error Unexpected 'const' for the line const t = 5. I don't understand why? My .jslintrc is as follows:
{
"node": true,
"indent" : 2,
"esnext": true,
"quotmark": "double",
"esversion": 6
}
any help would be appreciated. I'm using version 0.10.1 on a mac. If the problem is my version is old is there an easy way to get the latest version on a mac?
1
Douglas Crockford's profile photoDoug Kunzman's profile photo
2 comments
 
Yes, I'm using some old code. I just tried it with your tool and its great! Love your book bye the way.
Doug
Add a comment...

raal Bvv

Discussion  - 
 
Escaping a backtick in a template literal twice creates a wrong warning, const a = `\` blababa \``; 
1
Douglas Crockford's profile photoraal Bvv's profile photo
2 comments
 
I dont see it more complex than escaping quotes with \" in normal strings
Add a comment...

Douglas Crockford
owner

Discussion  - 
 
Should JSLint warn on get and set?

We are transitioning way from use of mutation and side effects. Getters and setters, by enabling side effects on simple assignment, seem to be going in the wrong direction.
61 votes  -  votes visible to Public
Warn on get and set
80%
No warning
20%
1
Vishal Srivastava's profile photo
22 comments
 
+Евгений Орехов The practicality is there. There are a lot of beautiful pattern that gets enabled by using a functional approach.

For example, if things dont change after being created then the concept of memoization gets enabled which improves performance significantly.

Hope that helps :)
Add a comment...