Why switch false always return first case? - javascript

I'm trying to understand switch behaviour when it deals with false.
let grade = 65;
switch(false){
case grade >= 90:
console.log(grade);
console.log("You did great!");
break;
case grade >= 80:
console.log("You did good!");
break;
default:
console.log(grade, "is not a letter grade!");
I don't understand why grade will always hit first case in the code above
I was expecting none of the case being fulfilled because of switch(false), and there should be no console log printed.

swtich compares the expression in the case with the value passed to switch.
(grade >= 90) === false
I strongly recommend only using simple values in cases and using if / else for more complex logic like you have here. Putting expressions in cases is unintuative.

You need to check against the opposite of the expression, because of the double negation.
switch (false) {
case !(grade >= 90): // code
}
vs
switch (true) {
case grade >= 90: // code
}

From MDN:
The switch statement evaluates an expression, matching the
expression's value against a series of case clauses, and executes
statements after the first case clause with a matching value, until a
break statement is encountered. The default clause of a switch
statement will be jumped to if no case matches the expression's value.
More details here: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/switch

It's because, it compares passed value (false) with case equation (which is also false in first case), so false === false is true (Yes it's ===, not ==), so it's going into the first case.

Related

How the indexOf method works in Javascript

I am taking a Javascript class and my instructor used the following code:
if('question-'.indexOf('question-1')){
//code
}
He claims this produces a true result and will execute the code in the code block (and it does work for him). I have tried running this in console, and I always get a -1 result. I am confused on how indexOf works in this case. (I know -1 means not found). But, in this case, some of the characters are there, just not every single one indicated in the string passed into indexOf. Does every single character have to be there and match? Or in this case was it producing a true result because some of the characters were there?
Does every single character have to be there and match?
Yes.
Or in this case was it producing a true result because some of the characters were there?
No. It's producing -1, which is a "not found" result, but -1 is a truthy value.
if (-1) { console.log("-1 is a truthy value"); } // This will be logged
if (0) { console.log("0 is a truthy value"); } // This won't be logged
if (1) { console.log("1 is a truthy value"); } // This will be logged
I assume your instructor is trying to demonstrate to you that you can't treat the return value of indexOf as a boolean.

datatype of prompt values in javascript in if else condition

let num1=prompt('Enter a num1:');
let num2=prompt('Enter a num2:');
if(num1 > 2)
document.write("num1 is greater num2");
else
document.write("num1 is less num2");
here, what is the type of num1 and num2 variable
if it is String datatype,so how it is comparing
Note: I am assuming that you meant to write if(num1 > num2). If this is not the case, refer to what #DaveNewton and #Ludolfyn mentioned about type coercion
Yes, it will return the variables with the type of string. However, it will compare them by the ordinal value of the characters, which will lead to unexpected (or rather expected, if you know how it works) results i.e. "15" will appear to be less than "4". Take a look at an ASCII table and notice that the code for "1" (49) is less than the code for "4" (52), which will cause this.
You should first cast them to ints using Number.parseInt(num1) and then compare:
let num1=Number.parseInt(prompt('Enter a num1:'));
let num2=Number.parseInt(prompt('Enter a num2:'));
if(num1 > num2)
console.log("num1 is greater num2");
else
console.log("num1 is less num2");
However, if the user enters a string which does not contain only digits (unless all of the digits are at the beginning of the string), this will return NaN, so be sure to check for that case with the Number.isNaN function

Assignment operator inside if clause assigns value and performs check?

I noticed something whilst debugging my code.
if(array.length=5){
console.log("it's 5 units long");
}
This not only makes the array size 5(assuming it performs the assignment every time) but it also performs the check in the if, resulting in a console output. Is this normal behaviour in Javascript and is this a valid shorthand for any real scenario?
The result of an assignment expression is the new value. Your code is equivalent to:
array.length = 5;
if (5) {
console.log("it's 5 units long");
}
And 5 is a truthy value, so the condition passes.
The following values are always falsy:
false
0 (zero)
"" (empty string)
null
undefined
NaN (a special Number value meaning Not-a-Number!)
All other values are truthy, including "0" (zero in quotes), "false" (false in quotes), empty functions, empty arrays, and empty objects.
I can contrive scenarios where this would be useful, but generally, no, it's not useful. At the very least, it's bad style, and shouldn't be used even if it can be.

parsing a number comparison string in javascript

So I'm wondering if there is a simple method for, i guess, parsing a string that contains a number comparison.
For example I have a variable that contains a string like this
str = "1>3";
Right now I'm using the math plugin to use math.eval(str) which returns a boolean but I feel like this is an awfully big resource to include just for a simple comparison.
My script is currently like this, and I love the simplicity I just hate having to use such a big resource for it.
if (math.eval(str) == true) {
//do something
} else {
// do something else
}
Any input on this matter would be greatly appreciated. I thank you in advance.
If you need that for friendly environment (non-public, no security considerations) you can use regular eval to compute result:
var result = eval("1>3");
Note that eval let you run any code and if you let user enter the "condition" and plan to use that for anything outside of personal calculator sample on you local machine - use proper parser that validates expressions and does not use arbitrary functions.
If you have such simple expressions, like
expression := number comparison_operator number
comparison_operator := < | > | = | ..
then it is also very simple to write a parser for this.
E.g. split the input string along the operator,
"1>3" ->
op = ">" ->
split: ["1", "3"] ->
num1_str = "1", num2_str = "3"
convert each number from its string representation to a number value.
num1 = 1, num2 = 3
Then apply the comparison operator.
switch (op) {
case "<":
return num1 < num2;
case ">":
return num1 > num2;
case "=":
return num1 == num2;
// <=, >=, !=, ..
default:
// unknown operator
}
This lib does a lot of things out of the box for expression parsing.

coffee script switch without break

Is it possible to use switch in coffeescript without break?
switch code switch (code) {
when 37 then case 37: break;
when 38 then -> case 38: break;
when 39 then case 39: break;
when 40 case 40:
... ...
I thought this will work but failed:
switch code
when 37 then continue
when 38 then continue -> not valid
when 39 then continue
when 40
...
Not really. From the docs:
Switch statements in JavaScript are a bit awkward. You need to remember to break at the end of every case statement to avoid accidentally falling through to the default case. CoffeeScript prevents accidental fall-through, and can convert the switch into a returnable, assignable expression. The format is: switch condition, when clauses, else the default case.
What you can do, though, is specify several values in a case, if they are to be treated equally:
switch day
when "Mon" then go work
when "Tue" then go relax
when "Thu" then go iceFishing
when "Fri", "Sat"
if day is bingoDay
go bingo
go dancing
when "Sun" then go church
else go work
You can use line continuation to help with this. For example:
name = 'Jill'
switch name
when 'Jill', \
'Joan', \
'Jess', \
'Jean'
$('#display').text 'Hi!'
else
$('#display').text 'Bye!'
Check it out in action here.
It's totally possible, just use a classic javascript and pass it through with backtics
`
switch (code) {
case 37:
case 38:
case 39:
case 40:
// do the work of all four
default:
//default
}
`
Old question already, but if you place the commas on the next line, it works as expected, without the backslash line continuation showed by #Ron Martinez
switch code
when 37
, 38
, 39
, 40
console.log "Some Number"
else
console.log "Default"
Which will compile to:
switch (code) {
case 37:
case 38:
case 39:
case 40:
return console.log("Some Number");
default:
return console.log("Default");
}

Categories

Resources