Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Regular parameters should not come after default parameters #2904

Open
kharandziuk opened this issue Mar 31, 2016 · 19 comments
Open

Regular parameters should not come after default parameters #2904

kharandziuk opened this issue Mar 31, 2016 · 19 comments

Comments

@kharandziuk
Copy link

> jshint -v
jshint v2.9.1

file to test the behaviour:

var a = function(x = 1, i) {}

the result of jshint a.js

a.js: line 1, col 26, Regular parameters should not come after default parameters.

1 error

content of .jshintrc:

{
  "asi": true,
  "esversion": 6
}
@jugglinmike
Copy link
Member

This message was originally implemented as a JSHint "error" (meaning it could
not be ignored): gh-1779. While it may have been a SyntaxError in some early
draft, it was not finalized in that way, so in gh-2543, we "downgraded" the
message to a warning. This means you may ignore it in JSHint 2.9.1 via
-W138.

That said, it remains unclear if this warning is appropriate at all. I
personally think that functions designed in this way are difficult to use, but
I'm not able to identify any potential code safety issues.

@rwaldron @caitp Do either of you have any thoughts on this?

@kharandziuk
Copy link
Author

kharandziuk commented Apr 18, 2016

Just want to mention that such kind of signature is a part of redux code samples. Look for the line:

function counter(state = 0, action) {

so, it is widely used, IMHO.

@rwaldron
Copy link
Member

rwaldron commented Apr 21, 2016

This sort of pattern is absolutely the definition of "lint".

so, it is widely used, IMHO.

I strongly disagree with the implication that a pattern which appears in redux is indicative of something "widely used". I looked through redux and found examples of counter(undefined, action) and I'm left wondering what the point of this could possibly be, considering every single one of them actually requires the action argument, or face a runtime error. If the action is always required and the state is optional, why require calls that must explicitly pass undefined—that defeats the purpose of default parameter values.

...I'm tempted to file a bug.


That said, it remains unclear if this warning is appropriate at all.

I believe it is, and anyone that doesn't want the warning is welcome to turn it off.

Feel free to close this @jugglinmike

@kharandziuk
Copy link
Author

@rwaldron ok, actually we don't discuss redux. Can you provide a sample of error which can appear with such signature?
For me it's just a property of language. So, what is the reason to mark it as "wrong"?

@rwaldron
Copy link
Member

Can you provide a sample of error which can appear with such signature?

The only runtime error you'll encounter is calling like: counter() and counter(undefined), but that's not my point. My point is that's terrible design and places an undue burden on the programmer and on their tooling. For example, a minifier could reasonably analyze the following:

function counter(action, state = 0) {
  return [action, state];
}
counter({});
counter({}, 0);
counter({}, undefined);

And produce:

function c(a,s=0){return[a,s]}
c({});
c({});
c({});

Whereas, putting the the default first:

function counter(state = 0, action) {
  return [state, action];
}
counter(0, {});
counter(undefined, {});

would produce:

function c(s=0,a){return[s,a]}
c(0, {});
c(undefined, {});

That's a fairly contrived example, but still illustrates my point that it makes the use of a default parameter completely and utterly pointless.

For me it's just a property of language.

Just because you can, doesn't mean you should.

@kharandziuk
Copy link
Author

So, on the moment you can't explain why it's a bad design except worrying about bugs in minifiers

@rwaldron
Copy link
Member

Requiring all call sites to pass an explicit undefined, for the sake of getting around a badly designed call signature is considered a bad practice and an incorrect use of default parameters.

@txm
Copy link

txm commented Jul 11, 2016

This behaviour is encouraged by React/Redux. I'm more likely to remove jshint than to remove React/Redux :/

http://redux.js.org/docs/basics/Reducers.html

One neat trick is to use the ES6 default arguments syntax to write this in a more compact way:

function todoApp(state = initialState, action) {
// For now, don’t handle any actions
// and just return the state given to us.
return state
}

@rwaldron
Copy link
Member

rwaldron commented Jul 11, 2016

@jugglinmike wdyt ^^ ?

@txm what happens to the action parameter that's never used?

@rwaldron rwaldron reopened this Jul 11, 2016
@jugglinmike
Copy link
Member

I'm still of the opinion that in the absense of a tangible hazard (and even in
the presence of otherwise-undesirable patterns), JSHint should remain silent.
That said, I'm having trouble understanding how @txm's example is distinct.

@thalesfsp
Copy link

How can I disasable it..?

@Pyo25
Copy link

Pyo25 commented Nov 5, 2016

@thalesfsp : Add /* jshint -W138 */ add the beginning of your file. (Make sure you're using jshint v2.9.1 or newer)

@derwaldgeist
Copy link

Stumbled upon the same problem with Redux. Can this be disabled in the .jshintrc config file, please?

@jugglinmike
Copy link
Member

@derwaldgeist Sure! Here's an example .jshintrc file that would silence the warning:

{
  "esversion": 6,
  "-W138": true
}

@jugglinmike
Copy link
Member

(By the way, JSHint's documentation has more information about disabling specific warnings.)

@derwaldgeist
Copy link

@jugglinmike Thanks. I did not know that it is possible to use the "-Wxxx" syntax in the .jshintrc file, too. I always used this at the top of a file. Great to know!

@marcusmotill
Copy link

With 'callback' being widely used as the last parameter of a function, this lint warning seems rather silly to me

@syida90
Copy link

syida90 commented Oct 18, 2017

openDialog(url, name, args = {}, pos) {
return new Promise(function(resolve, reject) {
chrome.windows.create({
url: url,
type: "popup",
width: pos && pos.width || undefined,
height: pos && pos.height || undefined,
left: pos && pos.left || undefined,
top: pos && pos.top || undefined
}, function(w) {

@andrew-st-angelo-77media

Apparently defaulting the other parameters to undefined is valid and pass the linting process. I'm not saying that's a better pattern but it passes the linting process.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

10 participants