admin管理员组文章数量:1302403
I am trying to validate a prompt in a JavaScript main function. Basically it asks for a number between 10 and 20. If the value does not fall within that range or is not a number, it should give an error message and ask again. If 0 is entered or the cancel button is pressed it should stop the routine pletely.
I know this is pretty bad code, but it works for me perfectly.
The problem I am having is when I try to validate it in JSLint I get the following error:
Expected 'else { if' and instead saw 'else if'.
} else if (amtEntered >= 10 && amtEntered <=20) {
If I unment the return 0
statement, the error is gone.
var amt;
var inputError = false;
do {
if (inputError) {
alert ("You have entered an error. \n Please try again.");
}
amt = prompt("Enter amount between 10 and 20: ","");
amt = Number(amt);
if (isNaN(amt)) {
inputError = true;
} else if (amt === null || amt === 0) {
// If amt is blank or cancel button pressed then exit loop and exit function.
inputError = false;
return 0;
} else if (amt >= 10 && amt <=20) {
inputError = false;
} else {
inputError = true;
}
}
while (inputError);
Would appreciate any tips or remendations on fixing this piece of code.
I am trying to validate a prompt in a JavaScript main function. Basically it asks for a number between 10 and 20. If the value does not fall within that range or is not a number, it should give an error message and ask again. If 0 is entered or the cancel button is pressed it should stop the routine pletely.
I know this is pretty bad code, but it works for me perfectly.
The problem I am having is when I try to validate it in JSLint I get the following error:
Expected 'else { if' and instead saw 'else if'.
} else if (amtEntered >= 10 && amtEntered <=20) {
If I unment the return 0
statement, the error is gone.
var amt;
var inputError = false;
do {
if (inputError) {
alert ("You have entered an error. \n Please try again.");
}
amt = prompt("Enter amount between 10 and 20: ","");
amt = Number(amt);
if (isNaN(amt)) {
inputError = true;
} else if (amt === null || amt === 0) {
// If amt is blank or cancel button pressed then exit loop and exit function.
inputError = false;
return 0;
} else if (amt >= 10 && amt <=20) {
inputError = false;
} else {
inputError = true;
}
}
while (inputError);
Would appreciate any tips or remendations on fixing this piece of code.
Share asked Sep 12, 2014 at 2:17 RickRick 2,30819 gold badges67 silver badges104 bronze badges 3- 4 Your code is fine...it is JSLint that is super strict/picky...for a more forgiving but still-useful lint try: javascriptlint./online_lint.php – The One and Only ChemistryBlob Commented Sep 12, 2014 at 2:21
- If we're going to nitpick why didn't you write amt === null as !amt ? – The One and Only ChemistryBlob Commented Sep 12, 2014 at 2:31
-
Comment out the
return 0;
line and the message goes away. Looks like thereturn
kicks in theuse_nested_if
option of JSLint – Paul S. Commented Sep 12, 2014 at 2:38
4 Answers
Reset to default 5Well, you could fix it by changing your if
statement to:
if (isNaN(amt)) {
inputError = true;
} else {
if (amt === null || amt === 0) {
// If amt is blank or cancel button pressed then exit loop and exit function.
inputError = false;
return 0;
} else {
if (amt >= 10 && amt <=20) {
inputError = false;
} else {
inputError = true;
}
}
}
But I think this is just JSLint being pedantic. What you have is actually valid syntax.
I believe the reason JSLint plains about things like this may be if you have code like:
if (condition)
do_something();
and someone later changes it to:
if (condition)
do_something();
do_something_else();
Without the braces, that code isn't going to work as expected. Whether you consider that a good enough reason to pepper your code with more braces is mostly a matter of style.
This particular case is plicated by the fact that it only happens when the return
statement is there, so the reasoning is more plex.
Looking at the source code, it appears to load up the entire if
block (the true branch) then check if the next token is else
. If the if
block has a disruptor (such as return
), it plains about an unnecessary else
(if the next token is else
) or lack of braces (if the next token set is else if
):
stmt('if', function () {
var paren = next_token;
one_space();
advance('(');
step_in('control');
no_space();
edge();
this.arity = 'statement';
this.first = expected_condition(expected_relation(expression(0)));
no_space();
step_out(')', paren);
one_space();
this.block = block('if');
if (next_token.id === 'else') {
if (this.block.disrupt) {
next_token.warn(this.elif ? 'use_nested_if' : 'unnecessary_else');
}
one_space();
advance('else');
one_space();
if (next_token.id === 'if') {
next_token.elif = true;
this.else = statement(true);
} else {
this.else = block('else');
}
if (this.else.disrupt && this.block.disrupt) {
this.disrupt = true;
}
}
return this;
});
The unnecessary_else
is easy to figure out, it's to catch things like:
if (condition) {
return 0;
} else {
do_something();
}
In that case, it's better written as:
if (condition) {
return 0;
}
do_something();
The use_nested_if
is more interesting in that, if braces are a good idea, they should be used all the time, not just when the block has a return
statement. I'm not sure why the author decided this was only a problem when a block returned.
If it really bothered you, you could no doubt modify the code to remove that check, not something I'd do lightly. Perhaps it may be better to ask the author to add the tolerate_non_nested_if
option to the software. Or, you could just ignore the warnings if you know it's okay.
And, on further reflection, it may be that the same reasoning is being used for both warnings - if you have an if
block that returns, any code after that should not be in the equivalent else
block, it should be stand-alone (but in the context of any outer if/else
blocks of course).
By that I mean you could probably use:
if (isNaN(amt)) {
inputError = true;
} else {
if (amt === null || amt === 0) {
// If amt is blank or cancel button pressed then exit loop and exit function.
inputError = false;
return 0;
} // no else needed here.
if (amt >= 10 && amt <=20) {
inputError = false;
} else {
inputError = true;
}
}
Ok, two issues, I think, if you let the double var
declaration and the alert
and prompt
slip by. (I've "fixed" the var
s by bining into one, added a jslint directive of browser:true
, and added window
before the alert
and prompt
, below.)
First, if you're literally using the code you've got above (and not checking it in the context of more code), you've got a return
outside of a function, which is a little wacky. So I've added wrapMe()
to wrap it so that JSLint stops getting confused by the return
, otherwise you get an unexpected return
error even after the block disruption stuff mentioned below.
Second, it is the return
, or, more specifically, the "block.disrupt" (link is to JSLint's code as of today) that's upsetting JSLint.
Crockford wants you to immediately stop the block if you're returning. No sense (in JSLint's mind) in else
after a return
. That block can be pulled out of the if
branching. That is, to JSLint, any code after a block containing a conditional disruption already is inherently an else equivalency, and to include the else
is misleading -- again, in a JSLintian sense.
You get the point in any event. You need to pull the else
after the block.disrupt
out, close out the if
that includes the disruption, and start a new statement.
Note that disrupt could also be a
break
, for instance. So if you had your original code and substituted abreak;
forreturn 0;
, you'd get the same admittedly somewhat misleading error. (And then you wouldn't have to wrap in a function.)
So the below is equivalent code to what you initially had in a format JSLint likes -- I believe. I'm a little tired.
/*jslint sloppy:true, white:true, browser:true */
function wrapMe() {
var amt, inputError = false;
do {
if (inputError) {
window.alert ("You have entered an error. \n Please try again.");
}
amt = window.prompt("Enter amount between 10 and 20: ","");
amt = Number(amt);
if (isNaN(amt)) {
inputError = true;
} else {
if (amt === null || amt === 0) {
// If amt is blank or cancel button pressed then exit loop and exit function.
inputError = false;
return 0; // BLOCK DISRUPTION!!! (Not sure why that felt Scott Pilgrim-y)
}
// If no disruption, continue.
if (amt >= 10 && amt <=20) {
inputError = false;
} else {
inputError = true;
}
}
}
while (inputError);
}
So instead of else if
-ing after a block disruption, just use a new if
.
JSLint is being picky about your code, which is valid, but (in my opinion) has a very odd structure. Consider a design like this instead
var amt,
fail = true;
// would use `while (amt = prompt("Enter amount between 10 and 20: ", ""))` personally
amt = prompt("Enter amount between 10 and 20: ", "");
while (amt) {
amt = +amt; // to Number
if (10 <= amt && amt <= 20) {
fail = false;
break;
}
alert("You have entered an error. \n Please try again.");
amt = prompt("Enter amount between 10 and 20: ", "");
}
if (fail) {
return 0;
}
It could have something to do with the return 0;
; an else
isn’t needed when that condition has been reached. Of course, since the return
is in an else if
, the fix is less straightforward, and the suggested fix doesn’t really make much sense.
Luckily, you can simplify!
var amt;
var inputError = false;
while (true) {
if (inputError) {
alert ("You have entered an error. \n Please try again.");
}
inputError = true;
amt = prompt("Enter amount between 10 and 20: ");
if (!amt) {
return;
}
amt = Number(amt);
if (isNaN(amt)) {
continue;
}
if (amt >= 10 && amt <= 20) {
break;
}
}
… assuming you have enough checks to warrant not just doing this:
if (!amt) {
return;
}
amt = +amt;
inputError = !(amt >= 10 && amt <= 20); // NaN will always pare as false here
本文标签: javascriptJSLint Expected 39elseif39 and instead saw 39else ifStack Overflow
版权声明:本文标题:javascript - JSLint: Expected 'else { if' and instead saw 'else if - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1741688490a2392584.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论