Is the syntax of this IF/OR statement wrong? - javascript

What is wrong with this code?
var variable = prompt("Choose answer1, answer2, answer3 or answer4");
if ((variable !== "answer1") || (variable !== "answer2") || (variable !== "answer3") || (variable !== "answer4")) {
return "You must choose one of these four options!"
}

Your current solution will be always true because variable will not allways be all answers at the same time.
You could use == instead of !== and then negate the whole expression:
if (!((variable == "answer1") || (variable == "answer2") || (variable == "answer3") || (variable == "answer4"))) {
or use and instead of or
if ((variable !== "answer1") && (variable !== "answer2") && (variable !== "answer3") && (variable !== "answer4")) {
in both cases the expression will be true if it is not any of the answers and false if it is one answer.

Related

if statement with javascript condition operator

just have 2 question regarding JS conditional operator, is the below 2 expression valid?
1.
if(isUser && isUser === true || isGuest && isGuest === true){
//...
}
I am wondering do I have to add () to make it like and still have the same functioning:
if((isUser && isUser === true) || (isGuest && isGuest === true)){
//...
}
const items = list.orderList && list.orderList.isUser === true || list.orderList.isGuest ? list.items : [];
I am wondering do I have to add () to make it like and functioning the same as above conditional operator:
const items = list.orderList && (list.orderList.isUser === true || list.orderList.isGuest === true) ? list.items : [];
As per Operator Precedence in the MDN docs, logical AND takes precedence over logical OR. Therefore,
expression1 || expression2 && expression3
will evaluate to
expression1 || (expression2 && expression3)
Therefore,
isUser && isUser === true || isGuest && isGuest === true
naturally evaluates to
(isUser && isUser === true) || (isGuest && isGuest === true)
anyway, so you do not need parentheses..
But since, in your second example, you want to evaluate OR then AND, you do need parentheses for it to evaluate the way you require, as
list.orderList && list.orderList.isUser === true || list.orderList.isGuest
will evaluate to
(list.orderList && list.orderList.isUser === true) || list.orderList.isGuest

I am trying to create a JavaScript program that prompts the user "enter yes or no to exit"

let q;
while ((q !== "yes")||(q !== "no")) {
q = prompt("yes or no?");
}
I've tried this and I couldn't understand why it wouldn't work since this:
while (q !== "yes") {
q = prompt("yes or no?");
}
works.
Uh, it seems that you used
while ((q !== "yes")||(q !== "no"))
This will always translate to true since q cannot be both "yes" and "no", it will always evaluate to true. The condition should be should be
while ((q !== "yes") && (q !== "no"))
The expression
(q !== "yes")||(q !== "no")
will always be be truthy, because q can't be both yes and no at the same time. If either condition is fulfilled, that while will be truthy, and the loop will continue.
Use && instead:
(q !== "yes") && (q !== "no")
Or, even more readably, use .includes:
while (!['yes', 'no'].includes(q)) {
let q;
while (!['yes', 'no'].includes(q)) {
q = prompt("yes or no?");
}

Error while accessing javascript array element inspite of having checks

I am doing following in my javascript code
if(
typeof player['stats'] != undefined &&
typeof player['stats']['guild'] != undefined &&
typeof player['stats']['guild']['master'] != undefined &&
typeof player['stats']['guild']['master']['since'] != undefined
)
However I get error:
Cannot read property 'since' of null
I have been stuck with this for a while. Can any javascript gurus help me please?
typeof returns string, so compare against "undefined"
if(
typeof player['stats'] != "undefined" &&
typeof player['stats']['guild'] != "undefined" &&
typeof player['stats']['guild']['master'] != "undefined" &&
player['stats']['guild']['master'] != null &&
typeof player['stats']['guild']['master']['since'] != "undefined"
)
Just check if the value is truthy:
if(
player['stats'] &&
player['stats']['guild'] &&
player['stats']['guild']['master'] &&
player['stats']['guild']['master']['since'] != undefined // only check the last one as it is probably not an object but another value such as 0 (depending on what your data looks like, if you have it as an object then just remove the != undefined check)
)
You could write a fairly simple object getter function which you pass the object and then a dot-delimited key to find a value like so:
function getObj(obj, key) {
return key.split(".").reduce((acc, cur) => {
if (acc !== undefined) {
return acc[cur];
}
return acc;
}, obj);
}
Then, you can grab the value that you want and see if it's undefined or not:
const player = {
stats: {
guild: {
master: {
since: '2004'
}
}
}
};
const since = getObj(player, 'stats.guild.master.since');
if (since) {
// do some code
}
This is a handy utility function you can use on any object and makes your if statement much prettier.
You can also avoid the multiple lookups with a temporary variable:
player = { stats: { guild: { master: null } } }
if ((temp = player.stats) &&
(temp = temp.guild) &&
(temp = temp.master) &&
(temp = temp.since) !== undefined)
console.log(true , temp)
else
console.log(false, temp)
player.stats.guild.master = { since: 'today' }
if ((temp = player.stats) &&
(temp = temp.guild) &&
(temp = temp.master) &&
(temp = temp.since) !== undefined)
console.log(true , temp)
else
console.log(false, temp)

Which Logic Operator Takes Precedence

So, I'm looking into writing a slightly more complex operation with logic operators in an if-else statement. I know I can do parentheses, and I know it's the better way of doing this, but I've gotten curious and so I'm going to ask. If I were to do something like this:
if (firstRun == true || selectedCategory != undefined && selectedState != undefined) {
//Do something
} else {
//Do something else
}
How will that be operated without the use of parentheses? I know there is an order of operations for logic operators, similar to PEMDAS, right? I'm curious if it'll be ran something like this:
firstRun == true || (selectedCategory != undefined && selectedState != undefined)
or maybe if the 'OR' operator takes precedence instead and it ends up going like:
(firstRun == true || selectedCategory != undefined) && selectedState != undefined
The full list would be nice, if you can find it somewhere, of the order of operations for this. Thanks!
My rule of thumb, which covers basically 99% of all use cases for conditional statements, is:
Grouping: ()
Member access . or [...]
Not: !
Comparison, e.g. < , >= , === , !=, ...
Logical AND &&
Logical OR ||
MDN gives you the exhaustive breakdown: JavaScript Operator Precedence
So for your example:
(firstRun == true || selectedCategory != undefined && selectedState != undefined)
equals
(firstRun == true) || ((selectedCategory != undefined) && (selectedState != undefined))
For anything more complex than the above mentioned cases, I would look into refactoring the code for readability's sake anyway!
There is a pretty good rule of thumb to this. Think of these operators as of mathematical ones:
AND is multiplication (eg. 0 * 1 = 0 => FALSE)
OR is adding (eg. 0 + 1 = 1 => TRUE)
When you remember this, all you have to know is that multiplication always comes before addition.
See this chart for precedence.
I'm not going to explain what happens because the next guy reading your code will think: "WTF? Does that do what it should?"
So the better solution is to wrap the terms in parentheses even if you know the precedence, applied it correctly and the code works
This follows the old wisdom that you shouldn't do everything you can just because you can do it. Always keep an eye on the consequences.
See Operator precedence.
&& is before ||, so your expression is equivalent to:
firstRun == true || (selectedCategory != undefined && selectedState != undefined)
It will be the first:
firstRun == true || (selectedCategory != undefined && selectedState != undefined)
As a general rule, in most programming languages, AND has higher precedence.
While logical operator precedence is not actually defined in the ECMAScript Specification, MDN does a pretty good job of it and even has a separate page for logical operators.
My concern I suppose, since logical operator precedence is not actually defined in the ECMAScript specification, each individual browser vendor can potentially be different (I'm talking to you, Internet Explorer!), so your mileage may vary.
In the event anyone wants to test this across different browsers, here's a test case fiddle: http://jsfiddle.net/HdzXq/
$(document).ready(function() {
function log(test) {
$('div#out').append($('<p />').text(test));
}
function testOperatorPrecedence() {
log('(false || false && false) === ' + (false || false && false).toString());
log('(false || false && true) === ' + (false || false && true).toString());
log('(false || true && false) === ' + (false || true && false).toString());
log('(false || true && true) === ' + (false || true && true).toString());
log('(true || false && false) === ' + (true || false && false).toString());
log('(true || false && true) === ' + (true || false && true).toString());
log('(true || true && false) === ' + (true || true && false).toString());
log('(true || true && true) === ' + (true || true && true).toString());
log('----------------------------');
log('(false || (false && false)) === ' + (false || (false && false)).toString());
log('(false || (false && true )) === ' + (false || (false && true)).toString());
log('(false || (true && false)) === ' + (false || (true && false)).toString());
log('(false || (true && true )) === ' + (false || (true && true)).toString());
log('(true || (false && false)) === ' + (true || (false && false)).toString());
log('(true || (false && true )) === ' + (true || (false && true)).toString());
log('(true || (true && false)) === ' + (true || (true && false)).toString());
log('(true || (true && true )) === ' + (true || (true && true)).toString());
}
testOperatorPrecedence();
});

What is the correct syntax for this 'OR' and 'AND' in this 'IF' statement?

I've got an 'if' statement and just wanted to know if these are both valid (which I believe they are) and if so what is the difference?
var type;
var type2;
if ((type == 'BOS'|| type == 'BPS'|| type == 'BRS') && (type2 == 'BOS'|| type2 == 'BPS'|| type2 == 'BRS))
OR
if ((type == 'BOS') || (type == 'BPS') || (type == 'BRS') && (type2 == 'BOS') || (type2 == 'BPS') || (type2 == 'BRS'))
Which has the correct syntax and do they do anything differently? is there a way to shorten this statement?
Thanks
The two statements are different. Yes, they are both valid statements, syntactically, but logically they differ. Since the && operator has a higher precedence than the || in javscript,
the resulting logic will evaluate as follows in statement 2:
1) (type == 'BRS') && (type2 == 'BOS')
2) (type == 'BOS') || (type == 'BPS') || (result of 1) || (type2 == 'BPS') || (type2 == 'BRS')
While in statement 1:
1) (type == 'BOS'|| type == 'BPS'|| type == 'BRS')
2) (type2 == 'BOS'|| type2 == 'BPS'|| type2 == 'BRS')
3) (result of 1) && (result of 2)
var type1;
var type2;
var correct_value = {
BRS: 1,
BOS: 1,
BPS: 1
};
if( correct_value[type1] && correct_value[type2]) {
alert('ok');
}
else {
alert('not ok');
}
Both conditional statement are valid but the result may be different.
The first statement will evaluate the OR value in the first bracket, and then evaluate the OR value in the second bracket, and finally evaluate the AND operator.
The second statement will evaluate the AND first and then evaluate from left to right without specific precedence (as in the first one).
You have to know which one do you actually use to determine the best refactoring code for it.
See this link: Operator Precedence.

Categories