if(e.FN === ' ' && e.GN === ' ' && e.LN === ' ' && e.DB === ' '){
This condition is never evaluated at all. Is this the way to check if all the values are null.
Right now you are checking if those values are all equal to a Space. The === not only compares the values but ensures they are the same type. However, if e.FN is null both e.FN == ' ' and e.FN === ' " will always return false. I think what you want is
if(e.FN === null && e.GN === null && e.LN === null && e.DB === null)
or even better, if you don't care if they are null, undefined or 0 you could do
if(e.FN && e.GN && e.LN && e.DB)
try:
if(e.FN === null && e.GN === null && e.LN === null && e.DB === null){
To check if all the values are null you should do:
if(e.FN === null && e.GN === null && e.LN === null && e.DB === null){
if the first value is not null javascript doesn't evaluate other condition, because if the first condition is false it's not possible for all the conditions to be true.
Related
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
can someone explain this comparison statement ?
I understand how to compare with && and || but the one liner below does something else
typeof(varName) === 'undefined' == 0
Lets say that varName is undefined. Your line of code goes through these steps (each new line is the next step):
typeof(varName) === 'undefined' == 0
typeof(undefined) === 'undefined' == 0
'undefined' === 'undefined' == 0
true == 0
false
Now lets say that varName is defined as equal to 5:
typeof(varName) === 'undefined' == 0
typeof(5) === 'undefined' == 0
'number' === 'undefined' == 0
false == 0
true
This is bad code. You can get the same result with typeof(varName) !== 'undefined'
typeof(varName) === 'undefined' == 0
The above expression can also be written as
!(typeof(varName) === 'undefined')
Instead of using Not operator (!) they have used == 0. But if you do ===0, it will not work because it will also check for datatype and will always return false.
example :
true == 0 => false
false == 0 => true
But if you use ===
true === 0 => false
false === 0 => false
Note: typeof(varName) === 'undefined' == 0 is a bad way to do it.
Use not operator:
!(typeof(varName) === 'undefined')
The two below snippets of JS code have had me confused, in my eyes both should work the same, due to short circuit evaluation. But for some reason snippet '1' causes the error (on the third line):
Cannot read property 'match' of undefined
Array 'a' holds 3 character values user entered into inputs. I want the code to return true if the char is undefined, an empty string, or a letter or number.
To be clear, this fails when a = ['a', '/'];
Snippet 1)
return typeof a[0] === 'undefined' || a[0] === '' || a[0].match(/^[a-z0-9]+$/i)
&& typeof a[1] === 'undefined' || a[1] === '' || a[1].match(/^[a-z0-9]+$/i)
&& typeof a[2] === 'undefined' || a[2] === '' || a[2].match(/^[a-z0-9]+$/i);
Snippet 2)
if (typeof a[0] === 'undefined' || a[0] === '' || a[0].match(/^[a-z0-9]+$/i)) {
if (typeof a[1] === 'undefined' || a[1] === '' || a[1].match(/^[a-z0-9]+$/i)) {
if (typeof a[2] === 'undefined' || a[2] === '' || a[2].match(/^[a-z0-9]+$/i)) {
return true;
}
return false;
}
return false;
}
return false;
Surely a[2].match should never be evaluated if a[2] is undefined due to the first conditional in the 'if'?
The answer is simple. Take a look to the order of operations .
AND binds more than OR.
In your Snippet 1 the expression is like:
a1 || b1 || (c1 && a2) || b2 || (c2 && a3) || b3 || c3
Your Snippet 2 is like:
(a1 || b1 || c1) && (a2 || b2 || c2) && (a3 || b3 || c3)
#Christoph is right but you also need to add something like !== null after match like
return (typeof a[0] === 'undefined' || a[0] === '' || a[0].match(/^[a-z0-9]+$/i) !==null ) && (typeof a[1] === 'undefined' || a[1] === '' || a[1].match(/^[a-z0-9]+$/i) !== null ) && (typeof a[2] === 'undefined' || a[2] === '' || a[2].match(/^[a-z0-9]+$/i) !== null);
You can take a look at this fiddle http://jsfiddle.net/dv360q1p/1/ which implements your question
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();
});
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.