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')
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
0 === (0 || 6) // returns false
false === (false || 6) // returns false
(false === false || false === 6) // returns true
(0 === 0 || 0 === 6) // returns true
console.log( 0 === (0 || 6) );
console.log( false === (false || 6) );
console.log( (false === false || false === 6) );
console.log( (0 === 0 || 0 === 6) );
what gives? I ran across this scenario earlier and don't get it.
0 === (0 || 6) // returns false
It's all about order of operations. That returns false because the parenthesis are evaluated first. So (0 || 6) returns 6 and 0 === 6 is false
false === (false || 6) // returns false
(false === false || false === 6) // returns true
(0 === 0 || 0 === 6) // returns true
The rest are easy to follow after that explanation.
0 === (0 || 6) is equivalent to 0 === 6 which is of course false.
false === (false || 6) is equivalent to false === 6 which is also obviously false.
(false === false || false === 6) is equivalent to true || false which is of course true.
(0 === 0 || 0 === 6) is also equivalent to true || false.
Look up "operator precedence". That'll help you wrap your head around javascript in the future.
First, you should know the operators priority.
Second, you should know how the operators work and what they return.
Here is the documentation you can take it as reference.
console.log( 0 === (0 || 6) );
// (0 || 6) returns 6 because 0 is falsy,
// so it becomes 0 === 6. It is obviously return false.
console.log( false === (false || 6) );
(false || 6) is equals (0 || 6), so we get (false === 6) = false.
console.log( (false === false || false === 6) );
// this is three part. === is prior to ||,
// so we should do (false === false) and (false === 6).
// (false === false) is true and (false === 6) is false,
// so we get (true || false) = true
console.log( (0 === 0 || 0 === 6) );
// (0 === 0) is true and (0 === 6) is false,
// so true || false is true.
By the way, most of the JavaScript operator do type conversion
whether the two sides is not the type the operator want.
Here's something you can take a look:
https://javascript.info/type-conversions
From your question, I am guessing you are not familiar with how AND & OR are used or works.
So,
| stands for bitwise OR
and, & stands for bitwise AND
It is a common method of writing AND as && and OR as ||.
For AND, following are the scenarios:
1 && 1 => 1
1 && 0 => 0
0 && 1 => 0
0 && 0 => 0
For OR, following are the scenarios:
1 || 1 => 1
1 || 0 => 1
0 || 1 => 1
0 || 0 => 0
In the above, 1 can be any non-zero integer or value (but we denote it by one, meaning high).
So, if you write,
0 === ( 0 || 6 ),
then, ( 0 || 6 ) is already true, then, if you compare true with 0, then it is always going to be false.
Whereas, if you you change the above condition as:
0 == ( 0 && 6 ), (EDITTED)
( 0 && 6 ) becomes false, and then 0 == false becomes true.
=== and == are different because the second one just checks if they are equal or not, but it does not check if they are exactly same. === checks if the values are identical, meaning exactly same.
I hope my answer was helpful.
If I compare "a" and "b", that should be false.
If I compare "a" and "a", that should be true.
If I compare "" and null, that should be true.
I could write my own method, but thought there was perhaps a JavaScript shortcut.
Edit: I was thinking something like this:
areDbSame(s1, s2) {
if (s1 === null) s1 = "";
if (s2 === null) s2 = "";
return s1 === s2;
}
Edit2: Settled on this version:
areDbSame(s1, s2) {
return (s1 === null ? "" : s1) === (s2 === null ? "" : s2);
}
Just before you test the equality of your string, you could do a simple one line enforcement, by converting to '' in the case of null. For example (if you also don't care about undefined, false, etc):
// testString becomes the one you are testing
var testString = myString || '';
If you only want to ensure null is blank
var testString = (myString === null) ? '' : myString;
Then you can simply do your string comparisons using testString, and not worry about the null equalities.
IMO this is the cleanest answer because it doesn't convolute the original equality testing of javascript strings. It is the same as saying, let's split the problem up into two parts.
1) When should my string be considered blank, and
2) Now I can just check for regular string equality.
function areEqualStrings(a, b) {
var otherEqualValues = ['', null];
if(typeof a === 'string' && typeof b === 'string') {
return a === b;
} else if(otherEqualValues.indexOf(a) > -1 && otherEqualValues.indexOf(b) > -1) {
return !a === !b;
} else {
return false;
}
}
When coercing JavaScript values, !null is true and !'' is true, so those would result in being equal.
Here's the test (screenshotted from my console):
This function should do it. It type checks first and short circuits otherwise.
function stringCompare(a, b) {
if (((a === null || typeof a === 'string') ||
(b === null || typeof b === 'string')) &&
((a === '' && b === null) ||
(b === '' && a === null) ||
(a === b))) {
return true;
}
return false;
}
No it hasn`t. The two first cases you can do naturally using operator =.
The third case it is impossible because "" is considered a empty string and null has any type. So they never can be true naturally. To do this, you have to write your own method.
Just to be clear. You can use operators = (equal) to do comparison:
== equal to
`x == 8 false
x == 5 true
x == "5" true
=== equal value and equal type
x === 5 true
x === "5" false
Hope it helps
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();
});
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.